【问题标题】:angular 1.5 component / default value for @ bindingangular 1.5 组件/@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 等服务并发布指向它们的链接。

标签: angularjs binding web-component


【解决方案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,这仍然有效。

    【讨论】:

    • 此解决方案比接受的解决方案更好,因为如果绑定是布尔值,则接受的解决方案不起作用。
    猜你喜欢
    • 2015-09-07
    • 2010-10-06
    • 1970-01-01
    • 2016-06-04
    • 2016-07-03
    • 2017-01-16
    • 2016-10-25
    • 1970-01-01
    • 2017-03-27
    相关资源
    最近更新 更多