AngularJS - 将输入值附加到列表并绑定到模型的指令

AngularJS - Directive to append input value to a list and bind to model

最终目标:将多个电子邮件地址与通知相关联,每个电子邮件地址都有一个频率设置(每日、每周、每月)。

我正在尝试定义一个作用于按钮元素的指令,这样,当单击按钮时,它会从输入元素中获取电子邮件地址,并从按钮旁边的下拉列表中获取频率,然后将它们插入输入+按钮下方的列表中,并将动态列表绑定到控制器上的 属性,以便在用户提交表单时将其发送到服务器。

表单已全部连接 - 这不是问题所在。

我只是想在构建指令方面得到一些帮助。

这是我目前的情况:

HTML:

<section ng-controller="notificationmanagement as vm">
    <input name="email" type="email"/>
    <select>
        <option>Daily</option>
        <option>Monthly</option>
        <option>Weekly</option>
    </select>
    <button data-cm-click type="button" class="btn btn-default"></button>
    <div ng-model="vm.Subscribers"></div>
</section>

指令:

commonModule.directive('cmClick', function () {
    return function (scope, element) {            
        element.bind("click", function () {

            // Is this the best way to get the value of the EmailAddress & Frequency?
            var emailAddress = element[0].parentElement.parentElement.children[0].value;
            var frequency = element[0].parentElement.parentElement.children[1].value;
            var spanEmailTag = angular.element('<span>' + emailAddress + '</span>');
            var spanFreqTag = angular.element('<span>' + frequency + '</span>');
            angular.element(spanEmailTag).appendTo(element[0].parentElement.parentElement);
            angular.element(spanFreqTag).appendTo(element[0].parentElement.parentElement);

            // How to make sure each added email+frequency is available 
            // in the array bound to 'vm.Subscribers'
        });
    }
});

'vm.Subscribers' 的结构应该是这样的,以便它被服务器使用:

vm.Subscribers = [ {'EmailAddress':'joe@email.com', 'Frequency':'Daily'}, {'EmailAddress':'bob@email.com', 'Frequency':'Monthly'} ];

注意:理想情况下希望在不依赖指令中的jQuery的情况下实现这一目标。

所有 pointers/help/advice 将不胜感激!

如果你想封装和重用一些功能,那么一定要使用指令。

但首先,了解 MVVM(模型-视图-视图模型)范例以及 Angular 如何实现它。

对于初学者,假设没有视图(因此,没有 DOM、指令等...)并且用户输入 神奇地暴露在 $scope 上(或者,如果您使用 ControllerAs - 作为控制器的 属性)。现在,从控制器开始构建应用程序的功能。用函数定义数据结构和行为。

app.controller("notificationmanagement", function(){
   // list of subscribers. You could also populate it from the backend. 
   this.subscribers = [];

   // this is where the details of a new subscriber will be stored
   // until subscriber is added
   this.newSubscriber = {EmailAddress: null, Frequency: null}; 

   // action to add a susbscriber
   this.addSubscriber = function(){
      this.subscribers.push(this.newSubscriber);

      // clear the object (it's not necessary to declare all the properties)
      this.newSubscriber = {};
   }
});

也就是说,简而言之,您的所有应用程序都在做。控制器不(也不应该)关心如何这是在视图中显示的。这就是 DOM 操纵不受欢迎的原因,因为它破坏了关注点分离。

现在,到视图。视图主要是声明性的:

<section ng-controller="notificationmanagement as vm">
   <input ng-model="vm.newSubscriber.EmailAddress" type="email>
   <select ng-model="vm.newSubscriber.Frequency">
      <option value="Daily">Daily</option>
      <option value="Monthly">Monthly</option>
      <option value="Weekly">Weekly</option>
   </select>
   <button ng-click="vm.addSubscriber()"> Add </button>

   <hr/>

   <h3>All subscribers:</h3>
   <div ng-repeat="s in vm.subscribers">
      <span>{{s.EmailAddress}}</span>
      <span>{{s.Frequency}}</span>
   </div>
</section>

注意 ng-model 指令如何将输入数据绑定到控制器的数据。注意 ng-click 调用控制器上的操作。请注意 ng-repeat 会根据该数据迭代并创建 DOM 元素。 View纯粹由数据驱动,由ViewModel.

引用

先了解这一点,然后再转向指令。