9

我正在为我们的应用程序中的常用控件创建一些可重用的指令。

例如,我们有一个用于数量文本框的 html 片段

<div class='amount'>
    <input type='text' ng-model='dollars'/>
</div>

从那里我开始创建我的指令:

app.directive("amount", function(){
    return {
        restrict: "E",
        template: "<div class='amount'><input type='text'/></div>",
        replace: true
    }
});

呈现以下内容<html/>

<div class="amount ng-pristine ng-valid" ng-model="dollars">
    <input type="text">
</div>

现在,ng-model<div/>不是我想要的,所以我需要创建一个范围并将其附加到,ngModel然后事情就又快乐了。

app.directive("amount", function(){
    return {
        restrict: "E",
        scope:{
            ngModel: "="
        },
        template: "<div class='amount'><input type='text' ng-model='ngModel'/></div>",
        replace: true
    }
});

一切正常,但是假设我还想添加一个ngChange指令,这是否意味着我需要再次更改我scope的包含ngChange: "="?像这样

app.directive("amount", function(){
    return {
        restrict: "E",
        scope:{
            ngModel: "=",
            ngChange : "="
        },
        template: "<div class='amount'><input type='text' ng-model='ngModel'/></div>",
        replace: true
    }
});

问题

我是否需要不断修改指令范围以包含我可能需要的无限数量的其他指令?或者有没有办法将<amount/>元素上的指令复制到<div/>而不是复制到<input/>

例如

<amount my-awesome-directive="" ng-disabled="form.$invalid" ng-model="dollarsAndCents" ng-click="aClick()" ng-show="shouldShow()"/>

变成

<div class="amount">
    <input my-awesome-directive="" type="text" ng-disabled="form.$invalid" ng-click="aClick()" ng-show="shouldShow()" ng-model="dollarsAndCents"/>
</div>

在预编译/后编译期间可以做些什么来复制它们还是我要解决这一切都错了?

更新

$compile()通过简单地循环所有属性并使用服务,我能够得到一些工作。它确实有效,但这是正确的吗?

app.directive("amount", function ($compile) {
    return {
        restrict: "E",
        template: "<div class='amount'><input type='text' /></div>",
        replace: true,
        compile: function compile(tElement, tAttrs) {
            return function (scope, iElement, iAttrs) {
                var attributes = $(iElement).prop("attributes");
                var $input = $(iElement).find("input");
                $.each(attributes, function () { //loop over all attributes and copy them to the <input/>
                    if (this.name !== "class") {
                        $input.attr(this.name, this.value);
                    }
                });
                $compile($input)(scope);  //compile the input
            };
        }
    };
});

鉴于以下内容<html/>,如果您向其中添加任何指令,<amount/>它将被复制到<input/>

<div ng-app="app">
        <amount ng-model="dollars" ng-change="changed = 'I Changed!!!'" ng-click="clicked= 'I Clicked It!'" name="amount"></amount>
         <h1>{{dollars}}</h1>
         <h2>{{changed}}</h2>
         <h3>{{clicked}}</h3>
        <input type="button" value="Remove" ng-click="items.splice(items.indexOf(item), 1)"/>
        <hr/>
</div>

更新了 jsfiddle

4

1 回答 1

-1

绑定控制器并轻松注入$scope

.controller('Amount', ['$scope', function($scope) {
    $scope.myMoney = '2';
}])

.directive("amount", function(){
    restrict: 'EA',
    replace: true,
    controller: 'Amount',
    template: "<div class='amount'><input type='text' ng-model='myMoney'/></div>",
    //Cleaner to include as URL if the partial is bigger.
    //templateUrl: '/views/amount.html',
    link: function(scope, controller) {}
});
于 2013-08-07T19:32:50.183 回答