2015-12-15 4 views
0

У меня есть 2 директивы: calculatorForm и calculatorAttribute. CalculatorForm - это родительская директива, в частности форма, содержащая теги ввода, которые являются директивами calculatorAttribute.Вызов функции ограничения родительской функции из дочерней директивы, которая запускает родительский наблюдатель

Я хочу, чтобы функция калькулятора CalculatorAttribute callForm изменяла переменную области видимости и запускала наблюдателя.

Вот мой код:

angular 
    .module('calculator') 
     .directive('calculatorForm', ['CalculatorDataModel', 'CalculatorPriceModel', 

      function(CalculatorDataModel, CalculatorPriceModel) { 

       return { 
        restrict : 'A', 
        replace : true, 
        templateUrl : function(element, attrs) { 
         return attrs.templateUrl; 
        }, 
        link : function(scope, element, attrs) { 
         scope.model = CalculatorDataModel; 
         scope.price = CalculatorPriceModel; 
         scope.model.initialize(calculator_data); 

         scope.updateSelectedSpecs = function(attribute_id, prod_attr_val_id) { 

          var selected_specs = JSON.parse(JSON.stringify(scope.model.selected_specs)); 
          selected_specs[attribute_id] = prod_attr_val_id; 
          scope.model.selected_specs = selected_specs;       
         } 

         scope.$watch('model.selected_specs', function(selected_specs, previous_selected_specs) { 
          if (selected_specs != previous_selected_specs) { 
           scope.model.setCalculatorData(); 
           scope.price.computePrice(); 
          } 
         }); 
        } 
       } 
      } 
     ]) 

     .directive('calculatorAttribute', [ 
      function() { 
       return { 
        restrict : 'A', 
        template : "<input type='radio' name='attr{{attribute_id}}' ng-value='prod_attr_val_id'/>", 
        replace : true, 
        link : function(scope, element, attrs) { 
         scope.attribute_id = attrs.attributeId; 
         scope.prod_attr_val_id = attrs.prodAttrValId; 

         element.on('click', function() { 
          scope.$parent.updateSelectedSpecs(scope.attribute_id, scope.prod_attr_val_id); 
         }); 

        } 
       } 

      } 
     ]); 

Моя проблема updateSelectedSpecs в родительском называется, но наблюдатель никогда не срабатывает, когда я использую element.on мыши в директиве ребенка.

Пожалуйста, помогите всем Спасибо !!!

ответ

0

Хорошо, после борьбы с этим немного, мне удалось произвести рабочую версию сократившиеся например:

angular.module('myApp', []) 
 
    .directive('calculatorForm', function() { 
 
    return { 
 
     restrict: 'A', 
 
     replace: true, 
 
     transclude: true, 
 
     template: '<div ng-transclude></div>', 
 
     link: function(scope, element, attrs) { 
 
     scope.model = {}; 
 
     scope.price = {}; 
 

 
     scope.updateSelectedSpecs = function(attribute_id, prod_attr_val_id) { 
 
      scope.$apply(function() { 
 
      console.log('update selected specs'); 
 
      var selected_specs = {}; 
 
      selected_specs[attribute_id] = prod_attr_val_id; 
 
      scope.model.selected_specs = selected_specs; 
 
      }); 
 
     } 
 

 
     scope.$watch('model.selected_specs', function(selected_specs, previous_selected_specs) { 
 
      console.log('new selected specs', selected_specs, previous_selected_specs); 
 
      if (selected_specs != previous_selected_specs) { 
 
      console.log("and they're different"); 
 
      } 
 
     }); 
 
     } 
 
    }; 
 
    }) 
 
    .directive('calculatorAttribute', function() { 
 
    return { 
 
     restrict: 'A', 
 
     template: "<input type='radio' name='attr{{attribute_id}}' ng-value='prod_attr_val_id'/>", 
 
     replace: true, 
 
     link: function(scope, element, attrs) { 
 
     scope.attribute_id = attrs.attributeId; 
 
     scope.prod_attr_val_id = attrs.prodAttrValId; 
 

 
     element.on('click', function() { 
 
      scope.$parent.updateSelectedSpecs(scope.attribute_id, scope.prod_attr_val_id); 
 
     }); 
 
     } 
 
    } 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> 
 
<form calculator-form ng-app="myApp"> 
 
    <input calculator-attribute attribute-id=1 prod-attr-val-id=1> 
 
</form>

Просто смотреть на консоли, чтобы увидеть его получения в $watch. Проблема заключалась в том, что вы не запускали цикл $digest в своей функции updateSelectedSpecs. Обычно $timeout, $http звонок или ngClick или другое событие запустит цикл $digest, но в этом случае вы должны запустить его самостоятельно, используя scope.$apply().

+0

AHA ПОЛУЧАЕТЕ! Вот почему мой наблюдатель работал раньше, когда у меня есть запрос $ http внутри функции updateSelectedSpecs. Блестящий @Ionut! scope. $ apply сделал трюк. Большое вам спасибо за борьбу с этим! –

+0

У меня есть следующий вопрос! Если у меня есть несколько экземпляров калькулятора, которые изолированы друг от друга. Функция updateSelectedSpecs запускается во все экземпляры из-за области. $ apply. Есть ли способ предотвратить это? –

+0

Просто установите для 'calculatorForm' область видимости изоляции, добавив параметр' scope: {} 'в возвращаемый объект функции' calculatorForm'. Он должен работать (см. Https://jsfiddle.net/souldreamer/evj03uux/) –

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