angular 1.5 组件/@binding 的默认值

Posted

技术标签:

【中文标题】angular 1.5 组件/@binding 的默认值【英文标题】:angular 1.5 component / default value for @ binding 【发布时间】:2017-05-18 23:04:08 【问题描述】:

有没有办法为组件的@绑定指定默认值。

我已经看到关于如何使用指令执行此操作的说明:How to set a default value in an Angular Directive Scope?

但是组件不支持编译功能。

所以,我有这样的组件:


  name: 'myPad',
  bindings   : layout: '@'

我想让我的组件的用户不必指定“布局”属性的值。所以...,这个:

<my-pad>...</my-pad>

而不是这个:

<my-pad layout="column">...</my-pad>

而且...这个“布局”属性应该被正在使用的 angular-material JS 消耗,因此需要在渲染 DOM 之前绑定它(因此材质 JS 可以拾取它并添加元素对应的类)。

更新,一些截图澄清情况:

组件定义:


  name : 'workspacePad',
  config : 
    templateUrl: 'src/workspace/components/pad/template.html',
    controller : controller,
    bindings   : 
      actions: '<', actionTriggered: '&', workspaces: '<', title: '@',
      flex: '@', layout: '@'
    ,
    transclude: 
      'workspaceContent': '?workspaceContent'
    
  

组件使用:

<workspace-pad flex layout="column" title="Survey List" actions="$ctrl.actions"
  action-triggered="$ctrl.performAction(action)">
  <workspace-content>
    <div flex style="padding-left: 20px; padding-right: 20px; ">
      <p>test test</p>
    </div>
  </workspace-content>
</workspace-pad>

我想在第二个屏幕截图(使用)选项中设置“flex”和“layout”。


更新

我的“解决方案”在我的组件的构造函数中有这个:

this.$postLink = function() 
  $element.attr("flex", "100");
  $element.attr("layout", "column");
  $element.addClass("layout-column");
  $element.addClass("flex-100");

我希望我不必写最后两行(addClass)...但是,因为我们没有链接并在组件中编译...我想我现在应该对此感到满意.

【问题讨论】:

如果你不要求用户指定 layout 属性,为什么要把它放在指令的范围内呢? 我需要在为组件(my-pad)生成的标签中拥有那个“布局”属性。否则我的页面布局会乱七八糟。如果用户忘记(不小心)为它指定一个值,我想给它一个默认值('column')。 您是否在链接函数中的任何位置使用layout 范围属性?您能否发布整个指令或至少相关部分的代码? hi frishi....我刚刚更新了帖子以添加代码的屏幕截图。谢谢! 谢谢,但请不要发布代码截图。始终使用内置的 Markdown 格式或使用 Plunkr 或 JSFiddle 等服务并发布指向它们的链接。 【参考方案1】:

首先有很棒的组件文档Angularjs Components`。还有你在做什么我以前做过,你可以通过使用它或在控制器本身中检查它来使其成为可选。

例如,您将绑定保留在那里,但在您的控制器中,您有类似的东西。

var self = this;

// self.layout will be the value set by the binding.

self.$onInit = function() 
    // here you can do a check for your self.layout and set a value if there is none
    self.layout = self.layout || 'default value'; 

这应该可以解决问题。如果没有,还有其他生命周期钩子。但我已经用我的组件完成了这项工作,甚至在 $onInit 之前运行的 $onChanges 中使用了它,您实际上可以在 $onChanges 函数中检查isFirstChange(),我很确定它只会在负载时运行一次。但是我自己没有测试过。

您可以查看其他生命周期钩子。

编辑

这很有趣,因为我以前用过这种方式。你可能会遇到其他问题。虽然这是一个想法。如果您将保存的值设置为父控制器中的 var 并使用 '

使用 angularjs 组件时,组件不会监视“@”,但使用“

【讨论】:

我尝试了这些回调,虽然我可以将 attr 添加到元素(使用 $element.attr()),但材质 JS 没有拾取它。我猜它在渲染周期中调用得太晚了。 我在它上面做了一个编辑,朝着不同的方向迈出了一步,但我以前也这样做过,以使这样的事情发挥作用。 嗨,它对我不起作用。我希望 angular 有类似的东西: flex: '@100' (@ 后面的任何内容都将被视为默认值)。现在我将确保用户(其他程序员)在使用组件时编写这些属性。 也许您可以设置一个未列出的具有默认值的单独绑定。像布局:'@',layoutDefault:'值'。并且在模板中有layout= $ctrl.layout || $ctrl.layoutDefault 。并玩弄它。我以前也做过哈哈。我有点困惑为什么这些都不起作用。 :) 事情是,在父模板(组件的用户)中,我不想在调用组件时写那个 attr。 i 并且在内部 div 中(在 workspacePad 的模板定义中)指定 attr 也无济于事。这些 attr 需要在 中;无论是否拼写出来。【参考方案2】:

你可以使用

$onChanges(layout) 
    if (! layout)  return; 
    this.setupLayout(); ---> or do whatever you want to do

【讨论】:

【参考方案3】:

在构造函数中定义绑定变量只会使用您想要的默认值启动变量,并且在初始化后,值会随着绑定更新。

    //ES6
    constructor()
      this.layout = 'column';
    
    $onInit() 
      // nothing here
    

【讨论】:

使用@ 绑定时不会替换这些值。 @StevenVachon 是的,我认为自最初发布以来,问题本身发生了很大变化。但是是的,赋值给评估表达式不是一个好主意:)【参考方案4】:

设置值如果未设置绑定值询问$onInit()中的值是undefined还是null

const ctrl = this;
ctrl.$onInit = $onInit;
function $onInit() 
  if (angular.isUndefined(ctrl.layout) || ctrl.layout=== null)
    ctrl.layout = 'column';

即使layout 的值是false,这仍然有效。

【讨论】:

此解决方案比接受的解决方案更好,因为如果绑定是布尔值,则接受的解决方案不起作用。

以上是关于angular 1.5 组件/@binding 的默认值的主要内容,如果未能解决你的问题,请参考以下文章

Angular 1.5 组件依赖注入

将服务注入 Angular 1.5 组件

属性中的 Angular 1.5 组件表达式“未定义”

有没有办法为 Angular 1.5 组件动态渲染不同的模板

Angular 1.5 组件示例

Angular 1.5 组件属性存在