如何在 AngularJS 指令中重命名 ngModel “require”

How to rename ngModel in AngularJS directive "require"

本文关键字:ngModel require 重命名 AngularJS 指令      更新时间:2023-09-26

我有这个简单的AngularJS指令:

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

我想将"ng-model"属性更改为"模型"的地方......但是我对如何将其传递给指令中的"require"选项有点迷茫。这是指令的完整代码:

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/

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

谢谢!

所以你想让你的指令更新父控制器?你不需要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";
  };
});
这是一个

典型的XY问题。你根本不需要ngModel这段代码,所以你的问题都是不正确的。你基本上是在问错事。

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

scope: {
    model: '='
}

然后在指令的链接函数中:

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

结果是这样的:https://jsfiddle.net/s2f5jbrd/1/

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

经过一番研究,我找到了获取指令子元素的 ngModel 控制器的方法。这是另一个指令作为示例,其中模型具有非标准的"ng-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();
                        }
                    };
                }
            }
        }
    }