使用ng-model,ng-model的AngularJS指令不会设置

时间:2015-03-04 16:32:22

标签: javascript html angularjs angularjs-directive

我想将一个指令应用于输入字段,具有回调函数,并使用ng-model。当我在指令中使用范围对象时,它会消除ng-model功能。

    var MyCtrl = ['$scope',
    function($scope,){

        $scope.aModel = 'HELLO!';

        $scope.myFunction = function(item){

            $scope.aModel = '';

        };

    }];

app.directive('myDirective',function(){

    return {
        restrict: 'A',
        scope: {
            myCallback: '&'
        },
        link: function(scope,element,attrs){

            element.bind('keyup',function(){

                scope.myCallback({item: 'test'});
                });
            }
       }
    });

HTML

<input type="text" my-directive my-callback="myFunction(item)" ng-model="aModel" />

Problem Plunkr

4 个答案:

答案 0 :(得分:0)

从隔离范围调用父作用域方法不会运行摘要周期,需要手动运行摘要周期。 因此,有三种方法可以手动运行摘要周期,scope.$evalAsync$timeout$apply()用于运行摘要周期。 其中$evalAsync is better way to run digest cycle,因为如果当前正在进行任何摘要,则$scope.$evalAsync()表达式将放置在每个$ digest迭代开始时刷新的异步队列中。< / p>

$apply()&amp; $timeout函数执行将与当前的摘要周期执行冲突。

<强>指令

app.directive('myDirective',function(){
return {
    restrict: 'A',
    scope: {
        myCallback: '&'
    },
    link: function(scope,element,attrs){

        element.bind('keyup',function(){
          scope.$evalAsync(function(){
            scope.myCallback({item: 'test'});
          })
        });

    }
}});

Updated Plunkr

答案 1 :(得分:0)

您可以使用scope.$apply(请参阅 updated Plunkr ):

app.directive('myDirective',function(){
return {
    restrict: 'A',
    scope: {
        myCallback: '&'
    },
    link: function(scope,element,attrs){

        element.bind('keyup',function(){

            scope.$apply(function() {
              scope.myCallback({item: 'test'});
            });


        });

    }
}});

由于您正在使用隔离范围,因此该功能发生在控制器的上下文之外,并且除非您强制执行新的摘要周期,否则模型不会更新。

答案 2 :(得分:0)

一个选项:

app.directive('myDirective',['$timeout', function($timeout){
return {
    restrict: 'A',
    scope: {
        myCallback: '&'
    },
    link: function(scope,element,attrs){
        element.bind('keyup',function(){
           $timeout(function() {
               scope.myCallback({item: 'test'});
           },10) 
        });
    }
}});

$timeout自动调用$ apply阶段。

AntiPattern

检查$scope.$$phase并明确致电$scope.$apply()

var app = angular.module('myApp',[]);
var MyCtrl = ['$scope',function($scope){
    $scope.aModel = 'HELLO!';
    $scope.myFunction = function(item){
        $scope.aModel = item;
        if (!$scope.$$phase) $scope.$apply();
    };
}];

app.directive('MyCtrl',MyCtrl);

app.directive('myDirective',function(){
return {
    restrict: 'A',
    scope: {
        myCallback: '&'
    },
    link: function(scope,element,attrs){
        element.bind('keyup',function(){
            scope.myCallback({item: 'test'});
        });
    }
}});

<强> DEMO

答案 3 :(得分:0)

我有一个过时的Angular版本。以为我失去了它。升级到v1.2.27,一切都解决了。我的原始代码工作正常。谢谢你的所有答案。