如何创建委托给ngModel的自定义AngularJS指令?

时间:2014-07-17 12:17:19

标签: angularjs angularjs-directive

假设我有这样的事情:

<div my-custom-root="root">
    <input type="text" my-custom-Path="path.to.somewhere" />
</div>

现在我想将其翻译成基本上与以下内容相似的内容:

<input type="text" ng-model="root.path.to.somewhere" />

我到目前为止指定了两个指令,获取所有对象等。这些为我提供了根对象和路径,但是如何从那些创建绑定?我缺少生成适当的ng-model指令或直接使用NgModelController

我创建了一个plunkr here,其中包含了我到目前为止所设置的内容。

为了便于参考,这里是我的指令代码,就像它们也可以在我的plunkr中找到:

app.directive('myCustomRoot', function() {
    var container;

    return {
        controller: function($scope) {
            this.container = function() {
                return container;
            };
        },

        compile: function() {
            return function ($scope, elm, attrs) {
                $scope.$watch(attrs.myCustomRoot, function(newVal) {
                    container = newVal;
                });
            };
        }
    };
});

app.directive('myCustomPath', function($parse) {
    return {
        require: '^myCustomRoot',

        link: function(scope, element, attrs, containerController) {
            var getter = $parse(attrs.myCustomPath);
            scope.$watch(function() {
                    return containerController.container();
                },
                function(newVal) {
                    if (newVal) {
                        alert('The value to be edited is: ' + getter(newVal) + '\nIt is the property "' + attrs.myCustomPath + '"\non Object: ' + JSON.stringify(newVal) + '\n\nNow how do I bind this value to the input box just like ng-model?');
                    }
                }
            );
        }
    };
});

你可以看到我的警报框中有所有可用的内容,但我不知道如何进行绑定。

1 个答案:

答案 0 :(得分:0)

我希望有一些方法可以编写someBindingService.bindInput(myInput, myGetter, mySetter),但我已经做了很多源代码阅读,不幸的是,绑定与编译密切相关。

但是感谢问题&#34; Add directives from directive in AngularJS&#34;我设法找到一种不那么优雅的方式,但它紧凑而有效:

app.directive('myCustomPath', function($compile, $parse) {
      return {
        priority: 1000,
        terminal: true,

        link: function(scope, element, attrs, containerController) {
          var containerPath = element.closest('[my-custom-root]').attr('my-custom-root');
          attrs.$set('ngModel', containerPath + '.' + attrs['myCustomPath']);
          element.removeAttr('my-custom-path');
          $compile(element)(scope);
        }
      }
    });

这使用了一点点jQuery,但是使用普通的jQLite也不应该这么做。