【问题标题】:Angular form 1.3 tightly coupledAngular 形式 1.3 紧耦合
【发布时间】:2015-05-12 20:13:17
【问题描述】:

你们中是否有人认为 Angular 1.3 中的表单导致控制器和 DOM 之间的紧密耦合?这是 Angular 的反模式。

例如,当为表单赋予 name='formExample' 属性时,要以程序方式将其设置为脏或无效,在控制器中我们必须执行 $scope.formExample.$setDirty()

这是一种不好的做法!

等待听到你的想法!

例子:

this.onSaveClicked = function () {
        that.saveMessage = that.SAVING_IN_PROGRESS;

        //Update project with changes
        ProjectsBLL.update($scope.entities.project.Model, function (data) {
            $scope.entities.project.Model = data;
            $scope.configurationForm.$setPristine();
            that.saveMessage = that.SAVING_FINISHED;
        }, null)
    }

【问题讨论】:

  • 你建议什么替代方式??
  • 你能在代码中给出一个具体的例子,当你在控制器中使用$setDirty时?然后答案可以提供其他编码方式。
  • 我有一个关于 setPristine() 的例子。只有当用户按下“取消”并且某些条件存在时,才调用 setPristine()。
  • @einav 你能把它作为代码放在问题中,也许是一个 Plunker 的链接?
  • @einav 我的意思是,如果您可以编辑问题并将代码放入其中,那么无需阅读 cmets 即可回答问题,并且代码格式合理。

标签: angularjs forms angularjs-scope


【解决方案1】:

听起来您不希望控制器中出现以下行

$scope.configurationForm.$setPristine();

为此,一种方法是:

  • 更改ProjectsBLL.update 以返回承诺而不是接受回调(如何做到这一点可能超出了这个问题的范围)。然后还从控制器中的函数返回来自then 的派生承诺:

    this.onSaveClicked = function () {
      that.saveMessage = that.SAVING_IN_PROGRESS;
    
      //Update project with changes
      return ProjectsBLL.update($scope.entities.project.Model).then(function (data) {
        $scope.entities.project.Model = data;
        that.saveMessage = that.SAVING_FINISHED;
      });
    }
    
  • 然后使用自定义指令而不是ng-click 来调用保存函数。可能有几种方法可以做到这一点,但一种是添加一种将函数作为属性的方法:

    <button type="button" my-submit="onSaveClicked()">Save</button>
    

    它添加了一个手动的click 监听器,在点击时调用传递的函数,并在其返回的promise 被解析后,在requireed 表单上调用$setPristine()

    app.directive('mySubmit', function($parse) {
      return {
        require: '^form',
        link: function(scope, element, attrs, formController) {
          var callback = $parse(attrs.mySubmit);
          element.on('click', function() {
            callback(scope, {}).then(function() {
              formController.$setPristine();
            });
          });
        }
      };
    });
    

这个版本,只是使用$timeout 来模拟对$http 的调用,可以在http://plnkr.co/edit/IdcfQ4N9MhDKdvyorzeO?p=preview 看到

【讨论】:

  • 感谢您的回答。但我不明白第一种方式。如何实现 $setPristine()?
  • @einav 我只给出了一种方法。我刚刚将其分为 2 个要点。
猜你喜欢
  • 2017-05-09
  • 2018-11-19
  • 1970-01-01
  • 2014-12-10
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
相关资源
最近更新 更多