如何在 Angular 1.5 组件中使用绑定

Posted

技术标签:

【中文标题】如何在 Angular 1.5 组件中使用绑定【英文标题】:How to use bindings in angular 1.5 components 【发布时间】:2017-08-23 20:56:06 【问题描述】:

在尝试编写一个简单的登录页面时,我在理解为什么 .components 绑定不起作用时遇到了一些困难。

例子

模板:login.html

    <form>
  <fieldset>
        <label>Email</label>
        <input id="email" type="email" ng-model="login.user.email">

        <label>Senha</label>
        <input type="password" ng-model="login.user.pass">

        <button ng-click="login.test(text: login.user)">
          Entrar
        </button>
  </fieldset>
</form>

组件:login.js

angular
  .module('app')
  .component('login', 
    bindings: 
      user: '<',
      test: '&'
    ,
    templateUrl: 'app/login/login.html',
    controller: function ($log) 
      var vm = this;
      vm.user = 
        mail: 'email@provider.net',
        pass: ''
      ;
      vm.test = consoleTest;

      function consoleTest(text) 
        $log.info('test! text:'+text);
      
    
  );

路线:router.js

angular
  .module('app')
  .config(routesConfig);

/** @ngInject */
function routesConfig($stateProvider, $urlRouterProvider, $locationProvider) 
  $locationProvider.html5Mode(true).hashPrefix('!');
  $urlRouterProvider.otherwise('/');

  $stateProvider
    .state('login', 
      url: '/login',
      component: 'login'
    );

路由未加载并显示错误:

stateService.ts:530 TypeError: Cannot read property '2' of null
    at http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7096:54
    at Array.map (native)
    at scopeBindings (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7096:7)
    at getBindings (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7101:17)
    at Array.map (native)
    at getComponentInputs (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7109:21)
    at config.templateProvider (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7074:34)
    at invokeResolveFn (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:2786:37)
    at processQueue (http://localhost:3000/bower_components/angular/angular.js:16843:37)
    at http://localhost:3000/bower_components/angular/angular.js:16887:27
$defaultErrorHandler @ stateService.ts:530
(anonymous) @ stateService.ts:352
processQueue @ angular.js:16843
(anonymous) @ angular.js:16887
$digest @ angular.js:17982
$apply @ angular.js:18280
bootstrapApply @ angular.js:1912
invoke @ angular.js:5003
doBootstrap @ angular.js:1910
bootstrap @ angular.js:1930
angularInit @ angular.js:1815
(anonymous) @ angular.js:33340
trigger @ angular.js:3435
stateService.ts:531 TypeError: Cannot read property '2' of null
    at http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7096:54
    at Array.map (native)
    at scopeBindings (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7096:7)
    at getBindings (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7101:17)
    at Array.map (native)
    at getComponentInputs (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7109:21)
    at config.templateProvider (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7074:34)
    at invokeResolveFn (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:2786:37)
    at processQueue (http://localhost:3000/bower_components/angular/angular.js:16843:37)
    at http://localhost:3000/bower_components/angular/angular.js:16887:27

只需删除绑定中的test: '&amp;' 属性,并且路由在控制台中加载时不会出现错误,但 ng-model 不会链接到控制器,因此它不会使用硬编码值更新输入字段。

我怎样才能使这些绑定起作用?

【问题讨论】:

为什么会有“vm.test = consoleTest;” ?它实际上是在替换绑定中的测试函数。 因为我不喜欢控制器内部的vm.test = function () ... 语法,所以我使用vm.test = functionName; 来更有条理,并且在发生错误时更容易追踪,因为不是另一个匿名函数 【参考方案1】:

你需要使用 angularjs lifecycle hooks 来初始化你想要的数据:

vm.$onInit = function() 
  vm.user = 
    mail: 'email@provider.net',
    pass: ''
  ;

您也不需要绑定测试,因为您可以访问组件中的控制器,因为您使用的是路由组件而不是无状态组件。

如果您使用的是无状态组件,则需要绑定测试并将其用作回调函数,以便在事件发生后将数据传回。

【讨论】:

所以你说的错误正是我定义的函数绑定? 我认为这是导致错误的原因,因为不需要绑定测试,因为它是在控制器中定义的。也不需要绑定用户,除非您将从解析或路由中传递数据。 哦,现在我明白了,我删除了绑定并在this.$onInit钩子函数中注入了变量初始化,它终于起作用了。那么绑定是针对组件的 html 标签属性中的参数? 是的,绑定用于将数据传递到组件中。因此,此数据可能来自解析,或者如果您在另一个 &lt;login bind-data="$ctrl.foo"&gt;&lt;/login&gt; 中使用该组件@

以上是关于如何在 Angular 1.5 组件中使用绑定的主要内容,如果未能解决你的问题,请参考以下文章

角度 1.5。如何使嵌入的模板绑定到组件范围

AngularJS 1.5 - 如何在组件上设置两种方式绑定

在 Angular 1.5 中使用“单向绑定”(<) 有啥意义?

angular 1.5 组件/@binding 的默认值

Angular 1.5 将数据从组件传递到控制器

如何在 Angular 1.5 中使用 HTML 选择调用父组件