Javascript 如何观看指令';s指令ng模型

Javascript 如何观看指令';s指令ng模型,javascript,angularjs,angularjs-directive,angularjs-scope,angular-ngmodel,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,Angular Ngmodel,我有一个在该视图中使用父范围的指令。此指令有一个使用隔离作用域的子指令。我试图让parent指令观察对child指令的ngModel所做的任何更改,并在发生更改时更新其自己的模式。下面是一个可能解释得更好的JSFIDLE: 代码如下: <div ng-app="app"> <div ng-controller="MyController"> <form name="someForm">

我有一个在该视图中使用父范围的指令。此指令有一个使用隔离作用域的子指令。我试图让parent指令观察对child指令的ngModel所做的任何更改,并在发生更改时更新其自己的模式。下面是一个可能解释得更好的JSFIDLE:

代码如下:

   <div ng-app="app">
        <div ng-controller="MyController">

            <form name="someForm">
                <div this-directive ng-model="theModel"></div>
            </form>

         </div>
    </div>

Javascript:

    var app = angular.module('app', []);
app.controller('MyController', function() {

});

app.directive('thisDirective', function($compile, $timeout) {

    return {
        scope: false,

        link: function(scope, element, attrs) {
            var ngModel = attrs.ngModel;
            var htmlText = '<input type="text" ng-model="'+ ngModel + '" />' +
                           '<div child-directive ng-model="'+ ngModel + '"></div>';

            $compile(htmlText)(scope, function(_element, _scope) {
                element.replaceWith(_element);                
            });

            // Not sure how to watch changes in childDirective's ngModel ???????

        }, // end link
    } // end return

});

app.directive('childDirective', function($compile, $timeout) {
    return {
            scope: {
                ngModel: '='            
        },  

        link: function(scope, element, attrs, ngModel) {
            var htmlText = '<input type="text" ng-model="ngModel" />';

            $compile(htmlText)(scope, function(_element, _scope) {
                element.replaceWith(_element);                
            });   

            // Here the directive text field updates after some server side process
            scope.ngModel = scope.dbInsertId;

            scope.$watch('dbInsertId', function(newValue, oldValue) {
                if (newValue)
                    console.log("I see a data change!");  // Delete this later
                    scope.ngModel = scope.imageId;
            }, true);

        },

    } // end return
});
var-app=angular.module('app',[]);
app.controller('MyController',function(){
});
app.directive('thisDirective',函数($compile,$timeout){
返回{
范围:假,
链接:函数(范围、元素、属性){
var ngModel=attrs.ngModel;
var htmlText=''+
'';
$compile(htmlText)(作用域,函数(_元素,_作用域){
元素。替换为(_元素);
});
//不确定如何查看childDirective的ngModel中的更改???????
},//结束链接
}//结束返回
});
app.directive('childDirective',函数($compile,$timeout){
返回{
范围:{
ngModel:“=”
},  
链接:功能(范围、元素、属性、模型){
var htmlText='';
$compile(htmlText)(作用域,函数(_元素,_作用域){
元素。替换为(_元素);
});   
//在这里,指令文本字段在服务器端处理后更新
scope.ngModel=scope.dbInsertId;
作用域.$watch('dbInsertId',函数(newValue,oldValue){
如果(新值)
console.log(“我看到数据更改!”;//稍后删除
scope.ngModel=scope.imageId;
},对);
},
}//结束返回
});

在该示例中,您可以看到在父指令及其子指令中有一个文本输入。如果在每个模型中键入,则会更新另一个模型,因为它们由
ngmodel
绑定。但是,子指令的文本输入会在服务器连接后更新。发生这种情况时,父指令中的文本输入不会得到更新。因此,我认为我需要观察child指令中的ngModel是否有任何更改我该怎么做?这有意义吗?

正如@shaunhusain提到的,您必须使用ngModelController与ngModel交互。在ngModelController上,您可以在
$modelValue
上设置手表,并且可以通过调用
$setViewValue
更改模型中的值。请记住,要使用ngModelController,您需要在指令定义对象中添加一个
require:“ngModel”

当您从angular外部(例如从数据库)获得一个值,并希望使用该值来更改模型值时,您需要将该代码包装在
范围内。$apply()

相关JSFIDLE

但是我认为使用
$setViewValue
并不正确。根据文档,这应该用于更新UI上显示的值,而不一定是模型值

实际上,还有另一种方法可以使这项工作更简单、更容易使用。只需使用
=attr
即可设置要在
thisDirective
childDirective
中使用的属性的双向绑定。然后,您可以在指令中设置ng模型属性设置,当您第一次使用它时,您甚至不需要知道它正在下面使用ng模型

下面的代码向您展示了我的意思:

app.directive('thisDirective', function($compile, $timeout, $log) {

    return {
        scope: {
            thisval: '='
        },

        link: function(scope, element, attrs) {

            var htmlText = '<input type="text" ng-model="thisval" />' +
                           '<div child-directive childval="thisval"></div>';

            $compile(htmlText)(scope, function(_element, _scope) {
                element.replaceWith(_element);                
            });

            scope.$watch('thisval',function(newVal,oldVal){
                $log.info('in *thisDirective* thisval changed...',
                          newVal, oldVal);
            });


        }, // end link
    } // end return

});

app.directive('childDirective', function($compile, $timeout, $log) {
    return {
        scope: {
            childval: '='
        },

        link: function(scope, element, attrs) {
            var htmlText = '<input type="text" ng-model="childval" />';

            $compile(htmlText)(scope, function(_element, _scope) {
                element.replaceWith(_element);                
            });

            scope.$watch('childval',function(newVal,oldVal){
                $log.info('in *childDirective* childval changed...',
                          newVal, oldVal);
            });

            // make believe change that gets called outside of angular
            setTimeout(function() {
                // need to wrap the setting of values in the scope 
                // inside of an $apply so that a digest cycle will be 
                // started and have all of the watches on the value called
                scope.$apply(function(){
                    scope.childval = "set outside of angular...";
                });
            },5000);

        },

    } // end return
});
app.directive('thisDirective',函数($compile,$timeout,$log){
返回{
范围:{
thisval:“=”
},
链接:函数(范围、元素、属性){
var htmlText=''+
'';
$compile(htmlText)(作用域,函数(_元素,_作用域){
元素。替换为(_元素);
});
作用域:$watch('thisval',函数(newVal,oldVal){
$log.info('in*thisDirective*thisval已更改…',
新瓦尔、旧瓦尔);
});
},//结束链接
}//结束返回
});
app.directive('childDirective',函数($compile,$timeout,$log){
返回{
范围:{
childval:“=”
},
链接:函数(范围、元素、属性){
var htmlText='';
$compile(htmlText)(作用域,函数(_元素,_作用域){
元素。替换为(_元素);
});
范围.$watch('childval',函数(newVal,oldVal){
$log.info('in*childDirective*childval已更改…',
新瓦尔、旧瓦尔);
});
//在外部调用的虚拟更改
setTimeout(函数(){
//需要在范围中包装值的设置
//在$apply中,这样就可以创建摘要周期
//已启动,并已调用值上的所有手表
作用域$apply(函数(){
scope.childval=“设置在角度以外…”;
});
},5000);
},
}//结束返回
});

更新的JSFIDLE示例:

您是否认为需要查找ngModelController以及如何在自己的指令中使用ng model?关于这个主题有一些不错的文档,您想要什么@乔瑟姆:我想这正是我想要的我将在我的代码中尝试它,并将重新更新。非常感谢你!Hi@JoseM在示例中效果很好,但我在代码中做了一些错误的事情。我的问题是:我是否需要在实s中使用
timeout
函数
app.directive('thisDirective', function($compile, $timeout, $log) {

    return {
        scope: {
            thisval: '='
        },

        link: function(scope, element, attrs) {

            var htmlText = '<input type="text" ng-model="thisval" />' +
                           '<div child-directive childval="thisval"></div>';

            $compile(htmlText)(scope, function(_element, _scope) {
                element.replaceWith(_element);                
            });

            scope.$watch('thisval',function(newVal,oldVal){
                $log.info('in *thisDirective* thisval changed...',
                          newVal, oldVal);
            });


        }, // end link
    } // end return

});

app.directive('childDirective', function($compile, $timeout, $log) {
    return {
        scope: {
            childval: '='
        },

        link: function(scope, element, attrs) {
            var htmlText = '<input type="text" ng-model="childval" />';

            $compile(htmlText)(scope, function(_element, _scope) {
                element.replaceWith(_element);                
            });

            scope.$watch('childval',function(newVal,oldVal){
                $log.info('in *childDirective* childval changed...',
                          newVal, oldVal);
            });

            // make believe change that gets called outside of angular
            setTimeout(function() {
                // need to wrap the setting of values in the scope 
                // inside of an $apply so that a digest cycle will be 
                // started and have all of the watches on the value called
                scope.$apply(function(){
                    scope.childval = "set outside of angular...";
                });
            },5000);

        },

    } // end return
});