【问题标题】:Why does `controllerAs` in JavaScript work but not `ng-controller=...as...` in HTML?为什么 JavaScript 中的 `controllerAs` 有效,但 HTML 中的 `ng-controller=...as...` 无效?
【发布时间】:2015-04-11 02:57:44
【问题描述】:

这行得通:

Plunker controllerAs in js

input-form.html

<form name="inputForm" ng-submit="inputForm.$valid && inputCtrl.emitData()" novalidate>
  <textarea name="topic1Data" ng-model="inputCtrl.inputValues.topic1Data" rows="10" cols="30" required></textarea>
  <button type="submit" class="btn btn-info btn-lg" ng-disabled="!inputForm.$valid">Compare</button>
</form>

inputForm.js

"use strict";

(function() {
  var inputForm = angular.module('input-form', []);

  inputForm.directive('inputForm', function() {
    return {
      restrict: 'E',
      templateUrl: 'input-form.html',
      scope: {data: "="},
      controllerAs: 'inputCtrl',
      bindToController: true,
      controller: function() {
        var inputCtrl = this;
        inputCtrl.inputValues = {topic1Data: 123456789};

        inputCtrl.emitData = function() {
          inputCtrl.data =  inputCtrl.inputValues.topic1Data;
        };
      }
    };
  });
})();

来源:https://stackoverflow.com/a/29558554/2848676

这不起作用:

Plunker controller as in html

input-form.html

<form name="inputForm" ng-controller="InputController as inputCtrl" ng-submit="inputForm.$valid && inputCtrl.emitData()" novalidate>
  <textarea name="topic1Data" ng-model="inputCtrl.inputValues.topic1Data" rows="10" cols="30" required></textarea>
  <button type="submit" class="btn btn-info btn-lg" ng-disabled="!inputForm.$valid">Compare</button>
</form>

inputForm.js

"use strict";

(function() {
  var inputForm = angular.module('input-form', []);

  inputForm.directive('inputForm', function() {
    return {
      restrict: 'E',
      templateUrl: 'input-form.html',
      scope: {data: "="},
      bindToController: true
    };
  });

  inputForm.controller('InputController', function(){
    var inputCtrl = this;
    inputCtrl.inputValues = {topic1Data: 123456789};

    inputCtrl.emitData = function() {
      inputCtrl.data =  inputCtrl.inputValues.topic1Data;
    };
  });
})();

我找到了一个article by Pascal Precht,它似乎说解决方案是bindToController,但我正在使用bindToController,但它仍然不起作用。

为什么 JavaScript 中的 controllerAs 有效,而 HTML 中的 ng-controller=...as... 无效?

【问题讨论】:

  • 据我了解 bindToController 仅适用于 controllerAs - github.com/johnpapa/angular-styleguide#style-y076
  • 究竟是什么不起作用?我试过你的 plunkr,它在 textarea 中显示 123456789。您预计会发生什么,以及会发生什么?
  • @JBNizet 抱歉,我把错误的 Plunker 链接放错了版本。我已经在问题中更正了它,但为了您的方便,这里是:plnkr.co/edit/jJr649vljMyqqZx8P9Um?p=preview。预期行为:给定在文本区域中输入的数字,当用户按下比较按钮时,该数字应显示为标签。它适用于 JS 中的 controllerAs,但不适用于 HTML 中的 ... as ...

标签: angularjs angularjs-directive


【解决方案1】:

bindToController 与在指令定义对象上定义的控制器一起使用:

.directive("foo", function(){
  return {
    //..
    bindToController: true,
    controller: "FooCtrl",
    controllerAs: "foo"
  };
});

换句话说,当$compile 服务运行并编译/链接指令时,它会收集指令并绑定到directive.controller 对象。那是“绑定”到隔离范围属性的控制器。

在您的情况下,您假设(错误地)在模板中使用ng-controller="FooCtrl as foo" 定义的控制器将以相同的方式工作。该假设没有依据,您链接到的文章从未将其作为一种选择。

模板可以实例化许多控制器,更不用说模板可以异步加载(使用templateUrl),所以bindToController 从来没有打算以这种方式使用。

【讨论】:

  • 谢谢。我似乎缺少一些知识。这两种创建控制器的方法似乎是等效的。您建议我阅读什么资源以了解 JavaScript 中的 controllerAs 语法和 HTML 中的 ng-controller=…as… 语法之间的区别?
  • @MichaelOsofsky 都充当别名,因为它们在as alias 别名下的作用域上“发布”控制器函数对象。但是在指令定义对象上定义控制器还有其他用途,例如通过require 使其可用,或者就此而言,启用bindToController
  • 我想知道如果在没有controller 的情况下指定了bindToController,AngularJS 是否应该给出错误。
  • 该错误一定是在最近的版本中引入的,因为我的版本 AngularJS 1.3.15 不会报告错误,而您的版本 1.4.0-rc.0 会。
  • 我在应用此解决方案时遇到的另一个问题是AngularJS "normalization"。我想将属性命名为 topic1Name 而不是 data。我终于发现我必须在 HTML 中将属性命名为 topic-1-name,在 JavaScript 中命名为 topic1Name。类似问题:stackoverflow.com/questions/29612749/…
猜你喜欢
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
  • 2013-08-25
  • 1970-01-01
  • 2022-01-12
相关资源
最近更新 更多