【问题标题】:Aurelia how to add Binding Behavior in a Custom Element and within its own namespace?Aurelia 如何在自定义元素及其自己的命名空间中添加绑定行为?
【发布时间】:2017-08-18 04:04:46
【问题描述】:

我正在构建一个 Aurelia 自定义元素并且我想使用一个特殊的绑定行为,但是我似乎无法在我的自定义元素类之外使用它(声明它)。另外,我想知道 Aurelia 中是否存在用于绑定行为和其他自定义内容的命名空间?

这是我要使用的绑定行为

可选绑定.js - code provided by another stack question

export class OptionalBindingBehavior {
  bind(binding, scope, interceptor) {
    binding.originalupdateTarget = binding.updateTarget;
    binding.originalTargetProperty = binding.targetProperty;
    binding.updateTarget = val => {
      if (val === undefined || val === null || val === '') {
        binding.targetProperty = null;
      } else {
        binding.targetProperty = binding.originalTargetProperty;
      }
      binding.originalupdateTarget(val);
    };
  }

  unbind(binding, scope) {
    binding.updateTarget = binding.originalupdateTarget;
    binding.originalupdateTarget = null;
    binding.targetProperty = binding.originalTargetProperty;
    binding.originalTargetProperty = null;
  }
}

我试过用这种方式导入

index.js

  import {MyCustomElement} from './my-element';
  import './optional-binding.js';

  export function configure(aurelia) {
    aurelia.globalResources('./my-element');
  }

  export {
    MyCustomElement
  };

还尝试直接在自定义元素内import './optional-binding.js';,但在所有情况下,它一直说找不到此绑定。

我还想知道如何将它变成它自己的命名空间(如果可能的话),以避免与可能由其他代码/项目全局声明的自定义绑定行为发生命名冲突。

编辑

我尝试了@janmvtrinidad 的建议,以使用require 导入绑定行为,但我得到了与之前尝试在 ViewModel 中导入它时类似的结果。另请注意,我所有的文件都在同一个目录中,因此使用 ./ 就足够了。到目前为止,我一直坚持在与自定义元素相同的文件中声明绑定行为,这是迄今为止唯一可行的方式。

在自定义元素视图(模板)内

<template>
    <require from="./optional-binding"></require>
    ...

我收到找不到它的错误

Cannot find module './aurelia-bootstrap-select/optional-binding'

整个代码/项目

我前段时间也在社区发布了这个插件,如果你想看完整的代码,插件是Aurelia-Bootstrap-Select。目前,如果有人想使用它并且也有OptionalBindingBehavior,那么就会发生名称冲突,这很糟糕。

注意

即使我发布了赏金,我仍在等待处理命名空间的正确方法以避免 Aurelia 中的名称冲突。

【问题讨论】:

  • 嗨@ghiscoding 我正在查看 ViewEngine 代码,了解 aurelia 如何与依赖项一起工作。似乎每个模板都有自己的 viewResources,因此当您在模板中需要它们时它应该可以工作,并且在使用资源时它会具有更高的顺序。并且还尝试了您使用的相同场景,并且它适用于我的情况。
  • @janmvtrinidad 我很高兴看到一个有效的答案,这可以帮助我和其他人。如果可行,我很乐意接受您的回答。

标签: javascript ecmascript-6 aurelia


【解决方案1】:

假设您的代码结构由Aurelia CLI 生成,其中元素、绑定行为等位于resources 文件夹中。现在您可以将绑定行为和自定义元素添加为globalResources。 在您的resources/index.ts 中,在config.globalResources([...]) 中添加您的绑定行为路径。

export function configure(config: FrameworkConfiguration) {
    config.globalResources([
        './value-converters/json',
        './binding-behaviors/intercept-one',
        './elements/pagination'
    ]);
}

现在您可以在 html 中不使用 require 的情况下在全球范围内使用您的资源。

在命名空间方面,当您尝试全局注册两个具有相同 ClassName 的资源时,Aurelia 会抛出错误。当你在这种情况下跑步时,你有两种选择。

  • 您可以使用@CustomElement@CustomAttribute 装饰器来覆盖现有的约定。默认约定将假定您的 ClassName 将从 InitCaps 转换为 dash-case。更多信息here
  • 或者你可以在你的html中明确地require它。它将覆盖 globalResources,然后在您的 html 中使用您的自定义资源,即使 globalResource 与您的自定义绑定行为/资源具有相同的 ClassName。

编辑

我还想知道如何将它变成它自己的命名空间(如果可能的话),以避免与可能由其他代码/项目全局声明的自定义绑定行为发生命名冲突。

目前是不可能的。 Aurelia viewResources 是一个单身人士。我相信,您可以使用require 将其添加到您的 html 中,如上面第二条所述。

【讨论】:

  • 感谢您的回复,但除非我误解了,否则这似乎无法回答我的主要问题。我不想让它成为全球性的,我想让它仅可用于该名称空间的自定义元素(如果自定义元素存在名称空间)。而且我之前已经尝试过 globalResources 似乎不适用于自定义元素。我的自定义元素是一个可供社区使用的插件,因此我希望避免命名冲突,此时我遇到了冲突,我看到了它的实际作用
  • viewResources 中的所有 bindingBehaviors 都是单例。所以方法是包含在你的html中或者使用viewResourcesdecorator
  • 就插件/功能而言,它目前不可用,正如 Rob here 所评论的那样。
  • 所以在阅读了Rob的这篇笔记之后,基本上意味着我的问题目前没有答案(主要是关于如何消除我仍然存在的名称冲突)。如果我想消除冲突,我将不得不使用一个永远不会在其他任何地方使用的名称,这不是命名空间修复,而是更多的唯一名称修复。
  • 使用 require 添加你的 bindingBehaviors 就可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 2016-10-06
  • 2015-08-07
  • 1970-01-01
  • 2015-12-02
  • 1970-01-01
相关资源
最近更新 更多