2015-05-02 3 views
0

Я пытаюсь реализовать пользовательскую директиву, которая перечисляет все доступные планы и позволяет пользователю выбирать один.Угловая директива: вернуть объект из коллекции

При выборе плана, родительский охват должен быть обновлен с выбранным объектом (это связанно с два способом связывания)

Он должен вести себя точно так же, как и угловые нг-опции делает, но у меня есть жесткий бой времени замена объекта 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, вы заметили, что я должен сравнивать объекты, используя поле идентификатора. Сравнение по == (=== в JS) не возвращает true.

Есть ли способ заменить родительскую область plan без танца с angular.copy available_plan, scope.plan и вынужден использовать сравнение полей id?

+1

Вы должны 'требовать:" ngModel "' - не использовать его как переменную с двухсторонней границей области. См. [Этот пример] (https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#example) о том, как создать настраиваемый элемент управления вводом, который по сути является тем, что у вас есть. –

ответ

1

Вы должны использовать require: 'ngModel' для ввода модели, прикрепленной к элементу или его родительскому элементу, к которому привязана директива. Вот demo.

+0

Я уверен, что раньше я это пробовал. И это не работает для объектов. Скоро приведу пример – AlexParamonov

+0

, я нашел проблему. Проблема в том, что я использовал абстрактное состояние ui-router с контроллером. Все дочерние состояния повторно используют этот контроллер. Но область не обновилась. Когда я явно определил контроллер в шаблоне или переместил абстрактное состояние формы определения 'controller' в дочернее состояние, он волшебным образом начнет работать. – AlexParamonov

+0

Я вижу, рад, что проблема решена :) – sol4me

0

Одним из способов решения этой проблемы заключается в обмене объекта и записи в его свойства

$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/

+0

'angular.copy', который я использовал в первом примере, является лучшим решением. Я использую 'require 'ngModel" 'прямо сейчас. Он работает для дочерних контроллеров. Но не для контроллеров, определенных в абстрактных состояниях. – AlexParamonov

Смежные вопросы