在使用模板的指令中更新ng-model

Dus*_*tin 15 javascript angularjs

我有一个像这样实例化的指令:

<datepicker ng-model="foo"></datepicker>
Run Code Online (Sandbox Code Playgroud)

在该指令中,datepicker标记被此模板替换:

template: '<div class="datepicker-wrapper input-append">' +
                     '<input type="text" class="datepicker" />' +
                     '<span class="add-on"><i class="icon-calendar"></i></span>' +
                   '</div>'
Run Code Online (Sandbox Code Playgroud)

我想要ng-model绑定的值是输入字段的值.什么是最好的方法,所以我保持ng-model的双向数据绑定?

Dre*_*ler 32

根据你的直通的复杂程度,你可以使用= scope在本地名称和ngModel之间进行双向绑定,就像这个小提琴一样:

http://jsfiddle.net/mThrT/22/

由于某种原因,我有一段时间设置小提琴(第一次用角度尝试),但这是拍摄的钱:

template: '<div class="datepicker-wrapper input-append">' 
        + '<input type="text" class="datepicker" ng-model="bar" />' 
        + '<span class="add-on"><i class="icon-calendar"></i></span>' 
        + '</div>',
scope: {
    bar: '=ngModel'
},
Run Code Online (Sandbox Code Playgroud)

  • 相同的例子,但没有孤立的范围:http://jsfiddle.net/gavinfoley/hZfE9 (3认同)

Ben*_*esh 10

有几种方法可以做到这一点..

ctrl调用链接函数的参数有一个函数.$setViewValue(valueHere),您可以使用该函数来设置ngModel引用的值.它将完成设置$ dirty等的工作.还有一个叫做.$viewValue可以用来获取当前值的属性.因此,您可以在isolate scope属性上设置$ watch以更新ngModel值.

更正确的方法仍然是在链接函数中,但它看起来像这样:

app.directive('myDirective', function() {
    restrict: 'E',
    require: 'ngModel',
    scope: {}, //isolate the scope
    template: '<div class="datepicker-wrapper input-append">' +
                         '<input type="text" class="datepicker" ng-model="date" />' +
                         '<span class="add-on"><i class="icon-calendar"></i></span>' +
                       '</div>',
    controller: function($scope) { 
    },
    link: function(scope, elem, attr, ctrl) {
       //get the value from ngModel
       scope.date = ctrl.$viewValue;

       //set the value of ngModel when the local date property changes
       scope.$watch('date', function(value) {
           if(ctrl.$viewValue != value) {
              ctrl.$setViewValue(value);
           }
       });
    }
});
Run Code Online (Sandbox Code Playgroud)