从子指令调用父指令范围函数,触发父观察者

时间:2015-12-15 10:35:31

标签: angularjs scope directive

我有2个指令:calculatorFormcalculatorAttribute。 CalculatorForm是父指令,特别是包含inputAttribute指令的输入标记的表单。

我想要calculatorAttribute调用calculatorForm函数来更改范围变量并触发观察者。

这是我的代码:

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时单击时,从未触发过观察者。

请大家帮帮忙!!!

1 个答案:

答案 0 :(得分:1)

好吧,经过一段时间的努力,我设法制作了一个精简版示例的工作版本:

&#13;
&#13;
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);
        });
      }
    }
  });
&#13;
<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>
&#13;
&#13;
&#13;

只需查看控制台即可看到它进入$watch。问题似乎是您没有在$digest函数中触发updateSelectedSpecs周期。通常$timeout$http调用,或ngClick或其他事件会为您启动$digest周期,但在这种情况下,您必须自己使用{{1}启动它}}