Angular 指令:return 对象来自集合

Angular directive: return object from collection

我尝试实现一个列出所有可用计划并允许用户选择一个的自定义指令。

选择计划后,必须使用所选对象更新父范围(它与双向绑定链接)

它的行为应该与 angular ng-options 的行为完全相同,但我很难与 Javascript 对象替换作斗争。

我现在所拥有的(删除了一些混乱):

在HTML中:

<choose-plan ng-model='plan' plans='plans' choose-plan-title='Premium plans' />

在控制器中:

 $scope.plan = {}  
 Plans.get (resource) ->
   $scope.plans = resource.plans
   return

它显然不适用于 $scope.plan = undefined,但我正在寻找可行的解决方案。

在 JS (Coffeescript) 指令中:

angular.module('tv-dashboard').directive 'choosePlan', [
  'lodash'
  (lodash) ->
    'use strict'
    restrict: 'E'
    scope:
      plan: '=ngModel'
      plan_collection: '=plans'
      title: '@choosePlanTitle'

    link: (scope, element, attrs) ->
      # HACK two way binding does not replace the value. Investigate
      scope.choosePlan = (available_plan) ->
        # scope.plan = available_plan # Does NOT update the parent scope binded ng-model
        angular.copy available_plan, scope.plan
        return

      scope.isSelected = (available_plan) ->
        return unless available_plan?
        available_plan.id == scope.plan.id

      presentPlans = (collection) ->
        angular.copy(collection).map (resource_plan) ->
          price_parts = resource_plan.interval_price.split '.'
          resource_plan['integer_price'] = price_parts[0]
          resource_plan['decimal_price'] = price_parts[1]
          resource_plan

      chooseDefaultPlan = (collection) ->
        scope.choosePlan lodash.last collection

      unWatchCollection = scope.$watch 'plan_collection', (collection) ->
        return unless collection? && collection.length > 0

        scope.plans = presentPlans collection
        chooseDefaultPlan scope.plans

        unWatchCollection()
        return
      return
    templateUrl: 'form/choose_plan.html'
]

但是如果您查看 isSelected 函数,您会注意到我必须使用 id 字段比较对象。 ==(JS 中的 ===)比较不 return 为真。

有没有一种方法可以替换父作用域 plan,而无需使用 angular.copy available_plan, scope.plan 并强制使用 id 字段比较?

您应该使用 require: 'ngModel' 来注入附加到指令绑定到的元素或其父元素的模型。这里有一个demo

解决这个问题的一种方法是共享一个对象并写入其属性

$scope.plan = {
  // value: set in directive
}

scope.choosePlan = (available_plan) ->
  scope.plan.value = available_plan
  return

scope.isSelected = (available_plan) ->
  return unless available_plan?
  available_plan == scope.plan.value

你的 jsfiddle 代码:http://jsfiddle.net/ht6tmhfu/1/
固定代码为 jsfiddle:http://jsfiddle.net/ht6tmhfu/3/