具有双向绑定和 ng-change 的 AngularJS 指令 [英] AngularJS directive with two-way binding and ng-change

查看:27
本文介绍了具有双向绑定和 ng-change 的 AngularJS 指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到过一种情况,我需要根据下拉列表的选定值更改输入框的输入类型.换句话说,如果用户从下拉列表中选择字符串",那么输入的类型应该是文本"等.我决定创建一个指令,因为我仍在学习 Angular,但我也不会复制块到处都是代码(我不止一次需要这个).

I have come across a situation where I need to change the input type of an input box based on the selected value of a dropdown. In other words, if the user selects 'String' from the dropdown then the type of the input should be 'text', etc. I decided to create a directive cuz I'm still learning Angular but also so I don't copy blocks of code all over the place (I need this more than once).

这是我尝试的内容:

(function () {
    "use strict";

    angular
        .module('app')
        .directive('dynamicTypeInput', dynamicTypeInput);

    function dynamicTypeInput() {
        return {
            replace: true,
            restrict: 'AE',
            require: ['ngModel', '^form'],
            scope: {type: '=', placeholder: '@'},
            templateUrl: 'app/common/dynamic-type-input/dynamic-type-input.tpl.html',
            link : function(scope, element, attrs, ngModel){

                //Watch for changes to ngModel, update scope.inputValue
                scope.$watch(function(){
                    return ngModel[0].$modelValue;
                }, function (value){
                    scope.inputValue = value;
                });

                //Watch inputValue, update the model
                scope.$watch('inputValue', function(value){
                    ngModel[0].$setViewValue(value);
                });

                //Setup ng-change
                if (attrs.ngChange) {
                    ngModel[0].$viewChangeListeners.push(function () {
                        scope.$eval(attrs.ngChange);
                    });
                }
            }
        };
    }
})();

注意:模板只是一个 ng-switch,它根据 scope.type 的值选择合适的输入框,输入都绑定到 scope.inputValue.

Note: The template is simply an ng-switch that selects the appropriate input box based on the value of scope.type and the inputs all bind to scope.inputValue.

我使用了this SO 问题来帮助我添加添加 ng-change 属性并正确触发的能力.根据那个答案,我需要从隔离范围中删除 ngModel,我不确定为什么需要这样做,但是,如果有人能解释一下,我将不胜感激.

I used the answer from this SO question to help me add the ability to add an ng-change attribute and fire correctly. According to that answer I needed to remove the ngModel from the isolated scope, I'm not sure why this is required but, if someone could explain it I'd be grateful.

从隔离范围中移除 ngModel 使得使用初始值实例化指令或在主控制器中更改模型时更新指令变得更加困难,所以现在我观看 ngModel[0].$modelValue 并在发生变化时更新本地值.

Removing ngModel from the isolated scope made it more difficult to instantiate directive with an initial value or have the directive update when the model is changed in the main controller so now I watch ngModel[0].$modelValue and update the local value if it changes.

虽然该指令有效并按照我的预期执行,但看起来有点复杂且效率低下,但我有没有办法以更简单的方式实现我想要的?

While the directive works and does what I expect it do but it all seems a bit convoluted and inefficient, is there no way I can achieve what I want in a more simple manner?

推荐答案

使用第二个答案到所引用的 SO 问题我解决了需要从隔离范围中删除 ngModel 以使 ngChange 工作的问题.这简化了指令,我可以按原样使用双向绑定.

Using the second answer to the SO question referenced I fixed the problem of needing to remove ngModel from the isolated scope in order to get ngChange to work. This simplified the directive and I can use two-way binding as is.

最终指令:

(function () {
    "use strict";

    angular
        .module('app')
        .directive('dynamicTypeInput', dynamicTypeInput);

    dynamicTypeInput.$inject = ['$timeout'];

    function dynamicTypeInput($timeout) {
        return {
            replace: true,
            restrict: 'AE',
            require: ['ngModel', '^form'],
            scope: {ngModel: '=', type: '=', placeholder: '@', ngChange: "&"},
            templateUrl: 'app/common/dynamic-type-input/dynamic-type-input.tpl.html',
            link: function (scope, element, attrs, ngModel) {

                scope.$watch('ngModel', function () {
                    $timeout(scope.ngChange);
                });

            }
        };
    }
})();

这篇关于具有双向绑定和 ng-change 的 AngularJS 指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆