emberjs - 重构自定义链接到htmlbars

时间:2015-11-29 07:47:46

标签: ember.js

以前我有自己的自定义link-to帮助,我在博客上写了here

使用把手我可以传递参数,如果值更改会导致重新渲染,例如,如果我绑定到具有isLoaded=false的模型,那么LinkView视图将重新呈现isLoaded=true或者值从undefined更改为其值。

以下是我的旧把手自定义链接帮助

Ember.Handlebars.registerHelper('resource-link-to', function(path, options) {
  var args = Array.prototype.slice.call(arguments, 1);
  var resource = this.get(path);
  var resourceRoute = resource.humanize();

  if (!options.fn) {
    options.types = ['STRING', 'STRING', 'ID'];
    options.contexts = [this, this, this];
    args.unshift(path);
    args.unshift(resourceRoute);
    args.unshift(resource.get('displayName'));
  } else {
    options.types = ['STRING', 'ID'];
    options.contexts = [this, this];
    args.unshift(path);
    args.unshift(resourceRoute);
  }
  return Ember.Handlebars.helpers['link-to'].apply(this, args);
});

此行中的ID标记表示它是绑定:

options.types = ['STRING', 'STRING', 'ID'];

我正在尝试在ember 1.13.11的htmlbars中复制此内容,并且我已经延长LinkComponent并覆盖willRender,如下所示:

export default LinkComponent.extend({
  willRender() {
    // FIXME: allow for css classes and query params
    Ember.assert('you must specify a resource', this.attrs.resource);

    const resource = this.attrs.resource;

    let resourceRoute = resource.value.humanize();

    if(typeToLinks[resourceRoute]) {
      resourceRoute = typeToLinks[resourceRoute];
    }

    this.set('attrs', {
      params: [resource.value.get('displayName'), resourceRoute, resource],
      view: this.parentView,
      hasBlock: false,
      escaped: true
    });

    this._super(...arguments);
  }
});

然后我这样称呼它:

{{resource-linkto resource=activity.reference}}

问题是resource可能处于isLoaded=false状态,因为它已部分解决。

如果像我以前在把手中那样解决了值,我该如何触发重新渲染?

1 个答案:

答案 0 :(得分:1)

好吧,我真的不知道你在第一个例子中如何利用isLoaded标志。如果我以任何方式误解你,请在以下解决方案上添加评论以纠正我。

  

如果像我以前在把手中那样解决了值,我该如何触发重新渲染?

通过在isLoaded的{​​{1}}属性上使用观察者并在属性更改时调用resource,这可能是最容易解决的:

rerender()

注意

调用export default LinkComponent.extend({ // isLoaded: Ember.computed.alias('resource.isLoaded') // OR you can create this alias and use `isLoaded` instead of `resource.isLoaded` throughout your code // rerender the component when the resource isLoaded becomes true onResourceLoaded: Ember.observer('resource.isLoaded', function() { if(this.get('resource.isLoaded')) { this.rerender(); } } willRender() { // ... } } 后,将再次调用willRender中的代码。

如果您只需要执行一次该代码,则可以使用以下component hooks代替rerender()

  • willRender如果您希望第一次将元素插入DOM中时运行代码。

  • didInsertElement如果您希望代码在创建并传递didInitAttrs组件后运行,则保证存在。