【问题标题】:AngularJS, $destroy event don't propagate changes for double binded parametersAngularJS,$destroy 事件不会传播双绑定参数的更改
【发布时间】:2023-03-23 04:21:01
【问题描述】:

我有一个具有独立作用域的简单指令,负责更改 a 值。当它被破坏时,我希望将值设置为未定义。但是,destroy 函数中的更改不会传播更改。

这里是代码。 问题再次是 outData 在此范围之外未设置为“未定义”

scope: {
    outData: '=ngModel',
},
link: function (scope, elem, attars) {
            scope.$on('$destroy', function () {
                scope.outData = undefined;
            })
}

我做了一个 plunker 来演示 problem。 这是一个错误吗?如果没有,是否有“$preDestroy”事件可以监听?

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    这里的问题是因为您将 outData 的值/引用更改为 undefined 而不再是外部值。您可以在指令中使用ngModelController,而无需在指令中声明新范围。

    在您提到的 Plunker 示例的指令中,您可以删除 scope 属性并添加 require: ngModel。这样您就可以在link 函数中注入ngModelController 并使用方法来更新外部值:

     app.directive('tvxSelect', function () {
        return {
            restrict: 'E',
            require: 'ngModel',
            template: '<select ng-model="intern">' +
            '<option value="nothing" selected>nothing<option>' +
            '<option value="forbidden">DONT SELECT<option>' +
            '</select>',
            link: function (scope, elem, attars, ngModelCtrl) {
                scope.$watch('intern', function (newVal) {
                  ngModelCtrl.$setViewValue(newVal);
                  ngModelCtrl.$commitViewValue();
                });
    
                scope.$on('$destroy', function () {
                    ngModelCtrl.$setViewValue('I TOLD YOU NOT TO SELECT');
                    ngModelCtrl.$commitViewValue();
                });
            }
        }
    })
    

    【讨论】:

    • 这个解决方案对我不起作用,因为我有多个输入/输出参数。它们不可能都是 ng-model。
    【解决方案2】:

    显然,从 $destroy 函数内部角播 $destroy 事件并在它返回之前将 $apply 和 $digest 设置为 noops。在摘要周期中无法注意到含义变化(据我所知)。 我最终通过像这样评估父范围上的实际对象来创建一个 setter 方法

     link: function (scope, elem, attrs, ngModelCtrl) {
    
       var dotPos = attrs.ngModel.lastIndexOf('.');
       var objString = attrs.ngModel.substr(0,dotPos);
       var paramString = attrs.ngModel.substr(dotPos+1,attrs.ngModel.length);
       var object = scope.$parent.$eval(objString);
    
       function setModel(val){
           object[paramString] = val
       }
    
       scope.$on('$destroy', function () {
           setModel(undefined);
       }
    }
    

    然后在 $destroy 事件中调用它。

    !OBS!这仅在您在 ng-model 上使用对象时才有效

    &lt;tvx-select ng-model="anyObject.value" ... /&gt;

    它不适合

    &lt;tvx-select ng-model="value" ... /&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 2017-09-04
      • 2019-02-17
      • 1970-01-01
      • 2018-06-29
      • 2012-12-10
      相关资源
      最近更新 更多