清除$ destroy

时间:2016-09-05 21:21:12

标签: javascript html angularjs

在我的单选按钮上,我有一个绑定到change事件的指令,并使用单选按钮值设置元素上定义的ngModel。这很好用。

但是,根据用户的选择,可以从DOM中删除隐藏单选按钮,我想在发生这种情况时清除控制器中的那些变量。我有$destroy事件的处理程序,我在其中将范围ngModel值设置为undefined

出于某种原因,在$destroy中设置范围值时,我的控制器中的范围值未在change处理程序中进行设置。

HTML

<div ng-repeat="item in category.items" class="field">
    <div class="ui radio checkbox">
        <input type="radio" value="{{item}}" sm-radio-button ng-model="submissions[category.model]" name="{{category.name}}" checked="" tabindex="0" class="hidden">
        <label ng-bind="item"></label>
    </div>
</div>

指令

.directive('smRadioButton', function(){
    return {
        scope: {
            ngModel: '='
        },
        link: function(scope, element, attrs){

            //Instantiate checkbox on load and set value to undefined
            element.parent().checkbox();
            scope.ngModel = undefined;


            element.on('$destroy', function(){
              scope.ngModel = undefined;
            })            

            element.on('change', function(e){
                scope.$apply(function(){
                    scope.ngModel = attrs.value;
                });
            });
        }
    };
})

其中category是许多配置对象之一,如:

  {
    name: 'Type',
    model: 'type',
    alwaysShow: true,
    items: ['Spending','Bills','Account Transfer','Deposit']
  }, 

注意:我没有在scope.$apply中使用$destroy,因为已经有正在进行的摘要周期。 $destroy实际上已被触发。

编辑:在其他几个元素上测试了这一点,似乎在$destroy中只看到该变量的局部范围发生了变化?如果我通过scope.$parent直接引用控制器,则控制器变量确实会发生变化。 (这是不理想的,因为这是几个ng重复深度,这意味着链接一堆$parent s)

2 个答案:

答案 0 :(得分:2)

您应该使用NgModelController方法。

取自NgModelController documentation

  

NgModelController为ngModel指令提供API。控制器包含用于数据绑定,验证,CSS更新以及值格式化和解析的服务。 它故意不包含任何处理DOM呈现或侦听DOM事件的逻辑。此类DOM相关逻辑应由其他指令提供,这些指令利用NgModelController对控件元素进行数据绑定。 Angular为大多数输入元素提供了这个DOM逻辑。在本页末尾,您可以找到一个自定义控件示例,该示例使用ngModelController绑定到contenteditable元素。

您应该使用$setViewValue然后,如上所示,由于API的性质,您需要调用$render来更新视图:

.directive('smRadioButton', function(){
    return {
        scope: {
            ngModel: '='
        },
        link: function(scope, element, attrs, ctrl){

            //Instantiate checkbox on load and set value to undefined
            element.parent().checkbox();

            // set the view value
            ctrl.$setViewValue(undefined);

            // render the changes
            ngModel.$render();

            element.on('$destroy', function(){
              ctrl.$setViewValue(undefined);
              ngModel.$render();
            });

            element.on('change', function(e){
                ctrl.$setViewValue(attrs.value);
                ngModel.$render();
            });

        }
    };
});

答案 1 :(得分:2)

要设置ngModel值,您可以使用ngModel.$setViewvalue(undefined),但同样需要ngModelngModelController指令函数中获取link

此外,您可以使用$parse API将值设置为ngModel指令(不需要ngModel控制器用于指令)。

所以你可以摆脱isolated scope(不确定这个指令到底在做什么,它只是你在代码中显示的那些,然后就不需要隔离了)

<强>指令

.directive('smRadioButton', function(){
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel){
            //var getter = $parse($attrs.ngModel);
            //setter = getter.assign;
            //Instantiate checkbox on load and set value to undefined
            element.parent().checkbox();

            element.on('$destroy', function(){
              ngModel.$setViewValue(undefined);
              //setter($scope, undefined);
            })            

            element.on('change', function(e){
                scope.$apply(function(){
                    ngModel.$setViewValue(attrs.value);
                    //setter($scope, attrs.value);
                });
            });
        }
    };
})