使用ng-model,bindToController在一个页面上的多个指令

时间:2015-10-23 08:17:27

标签: javascript angularjs directive angular-ngmodel

我已经创建了一个电子邮件订阅指令,您附加到表单并在提交时,它会将电子邮件发送到Campaign Monitor,yada yada ya。

我遇到了一个奇怪的问题,其中ng-model突破了一个孤立的范围和bindToController。

Angular Directive:

    angular.module('quiip.directives')
    .directive('subscribeToNewsletter', subscribeToNewsletterDirective);

    function subscribeToNewsletterDirective(){
        return {
            restrict: 'A',
            scope: {},
            bindToController: true,
            controllerAs: 'subscribe',
            controller: subscribeToNewsletterCtrl,
            link: function(scope, el){
                el.addClass('subscribe-to-newsletter');
            }
        }
    }

HTML表单,一般结构。这取决于表单的使用位置。这是硬编码的(即不是模板):

    <form subscribe-to-newsletter ng-submit="subscribe.submitEmailSubscribe()" ng-class="{ error : subscribe.states.error, success : subscribe.states.success }">
        <div class="status-icon loading" ng-show="subscribe.states.loading"><i class="fa fa-circle-o-notch fa-spin"></i></div>
        <div class="status-icon success" ng-show="subscribe.states.success"><i class="fa fa-check"></i> Subscribed!</div>
        <input type="email" placeholder="Email Address" ng-model="subscribe.email">
        <button type="submit" class="hollow">Subscribe to newsletter</button>
    </form>

表格的另一个例子:

    <form class="row" subscribe-to-newsletter ng-submit="subscribe.submitEmailSubscribe()" ng-class="{ error : subscribe.states.error, success : subscribe.states.success }">
        <div class="status-icon loading" ng-show="subscribe.states.loading"><i class="fa fa-circle-o-notch fa-spin"></i></div>
        <div class="status-icon success" ng-show="subscribe.states.success"><i class="fa fa-check"></i> Subscribed!</div>
        <div class="small-12 medium-6 columns">
            <input type="email" ng-model="subscribe.email" placeholder="email" name="email-address">
        </div>
        <div class="small-12 medium-6 columns">
            <button type="submit" class="expand">Subscribe</button>
        </div>
    </form>

正如您所见in this screenshotng-model正在逃避隔离范围和controllerAs / bindToController(我甚至不确定我需要同时使用两者?)并在页面中传播。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

您正在混合使用隔离范围的指令与操纵DOM的指令。

隔离范围

根据docs创建隔离范围允许您

  

将指令内的范围与外部范围分开,然后将外部范围映射到指令的内部范围。

如果要在父作用域内隔离表单范围并将模型公开给该父作用域,则可以实现它:

Request::json()

然后您有一个单独的表单代码模板文件:

<!-- parent template -->
<div> <!-- just an example parent template -->

    <subscribe-to-newsletter subscribe-email="subscribe.email"></subscribe-to-newsletter>

</div>

然后你的指令看起来像这个

<form ng-submit="subscribe.submitEmailSubscribe()".... <!-- note no use of directive name here -->
    ...
</form>

操纵DOM

要操纵DOM,您可以创建一个返回链接函数的指令(几乎就是您已经在做的但没有隔离范围)。

一个很好的例子是in the docs。对于您的编码风格,您的指令可能如下所示:

// subscribeToNewsletter.directive.js
angular.module('quiip.directives')
.directive('subscribeToNewsletter', subscribeToNewsletterDirective);

function subscribeToNewsletterDirective() {
    return {
        restrict: 'A',
        scope: {
            subscribeEmail: '=' // bi-directional binding to the model passed into your template handy for attaching data to a parent form object
        },
        bindToController: true,
        controllerAs: 'subscribe',
        controller: subscribeToNewsletterCtrl,
        replace: true,
        templateUrl: 'path/to/your/form/template'
    }
}

最后...

如果在不同视图中有两种不同的形式,使用相同的模型名称,那么最好为每个视图使用不同的控制器以避免命名空间冲突。