如何在AngularJS指令中重命名ngModel"要求"

时间:2016-03-22 00:24:52

标签: javascript angularjs angularjs-directive angular-ngmodel

我有这个简单的AngularJS指令:

<my-directive ng-model="name"></my-directive>

我想改变&#34; ng-model&#34;归因于&#34;模型&#34; ...但我在如何将其传递给&#34;要求&#34;指令中的选项。 这是指令的完整代码:

myApp.directive('myDirective', function($timeout) {
    return {
        restrict: 'E',
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            ngModel.$render = function() {
                $timeout(function() {
                    ngModel.$setViewValue('StackOverflow');  
                }, 5000);                
            };
        }
    };
});

这里有一个小提琴:https://jsfiddle.net/cg2enqj2/1/

有人可以帮助我了解它是如何(以及如果)可能的吗?

非常感谢你!

3 个答案:

答案 0 :(得分:1)

所以你希望你的指令更新父控制器?您不应该需要ngModel来执行此操作。控制器设计用于存储要在前端显示的值,并包含获取和设置它们的操作。如果你想让一个指令更新父元素,你应该使用服务/工厂。

但是,可以稍微设计一下,只需在屏幕元素之间移动一些值即可。我更喜欢从指令访问我的范围,通常只是读取值,然后让控制器也处理更新,但从指令调用它。这可能是Angular世界的致命罪,但它对我来说很有效。

在这个例子中,我从你的指令中剥离了ngModel,并添加了一个按钮,该按钮从我添加到指令模板的按钮调用更新。

https://jsfiddle.net/jimmeyotoole/13kfdq8x/1/

var myApp = angular.module('myApp', []);

myApp.directive('myDirective', function($timeout) {
  return {
    replace: true,
    template : '<div><p> directive value = {{name}}</p> <button ng-click="activate()">Activate!</button><p>example private {{privatevar}}</p>',
    link: function(scope) {
        scope.privatevar="ZZZZ";
    }
   }
  });

myApp.controller('MyCtrl', function($scope, $timeout) {
  $scope.name = 'Superman';
  $scope.activate = function () {
    $scope.name = "I'm no Superman";
  };
});

答案 1 :(得分:1)

这是典型的XY problem。您根本不需要ngModel,因此您的问题都是错误的。你基本上都在问错误。

您要做的是使用指令属性在外部作用域和指令之间进行通信。这完全可行,但您可以在指令配置对象上使用ngModel属性,而不是使用scope

scope: {
    model: '='
}

然后在指令的链接功能中:

$timeout(function () {
    scope.model = 'lol';
}, 1000);

结果如下:https://jsfiddle.net/s2f5jbrd/1/

此外,如果您更新到AngularJS 1.5,由于.component函数,语法变得更加清晰。在应用所有良好实践(组件,绑定,控制器,控制器为)后,结果如下:https://jsfiddle.net/s2f5jbrd/4/

答案 2 :(得分:0)

经过一番研究后,我找到了获取指令子元素的ngModel控制器的方法。 这是另一个指令作为示例,其中模型具有非标准“ng-model”名称,但只是“model”:https://plnkr.co/edit/UgeYT6tbVpMal7KbPNDC?p=preview

function lgDate($compile, $filter) {
        var directive = {
            restrict: 'E',
            scope: {
                model: "=",
            },
            compile: compile
        };

        return directive;

        function compile(element, attrs) {
            return {
                pre: function (scope, element, attrs) {
                    var template = '<input ng-model="model" ng-keyup="keyup($event.keyCode)" ui-mask="99/99/9999" ' +
                                   'ng-pattern="/(\\d{4}(?!\\d))?([2-9]\\d{3}|1[8-9]\\d{2}|17[6-9]\\d|175[3-9])/" type="text" ';

                    if (element.attr('class')) {
                        template += 'class="' + attrs.class + '" ';
                        element.removeClass(attrs.class);
                    }

                    if (element.attr('name')) {
                        template += 'name="' + attrs.name + '" ';
                        element.removeAttr('name');
                    }

                    if (element.attr('required')) {
                        template += 'required ';
                        element.removeAttr('required');
                    }

                    template += '/>';

                    element.html(template);
                    element.removeClass(attrs.class);

                    $compile(element.contents())(scope);
                },
                post: function (scope, element, attrs) {
                    var ctrl = element.find('input').controller('ngModel');

                    ctrl.$formatters.push(function (data) { // model - view
                        data = $filter('date')(data, 'ddMMyyyy');
                        return data;
                    });

                    ctrl.$parsers.push(function (data) { // view - model
                        var year = data.substr(-4);
                        var month = data.substr(2, 2);
                        var day = data.substr(0, 2);

                        data = (year && month && day) ? year + '-' + month + '-' + day + 'T00:00:00.000Z' : '';
                        return data;
                    });

                    scope.keyup = function (key) {
                        if (key === 68) { // D key
                            scope.model = new Date().toJSON();
                        }
                    };
                }
            }
        }
    }