【问题标题】:Angular 2 expression parser and ng-init directiveAngular 2 表达式解析器和 ng-init 指令
【发布时间】:2017-01-05 17:18:39
【问题描述】:

基本上我正在寻找一种方法来实现 Angular 1.x ngInit 指令的对应项。

我知道ngOnInit 钩子以及它是初始化代码的推荐位置这一事实。我认为ngInit 指令是一种快速、声明性的方式来原型化或修复通常不应在编写良好的生产代码中使用的组件(尽管开发人员有权选择最适合他/她的组件)。

init dummy 指令中做类似的事情

<p [init]="foo = 1; bar()"><p>

多次评估表达式并导致

模板解析错误:

解析器错误:绑定不能包含赋值

错误。

在 Angular 1.x 中,只需使用

$parse($attrs.init)($scope)

如何使用 Angular 2 解析器并可能对其进行扩展以在组件初始化时评估 foo = 1; bar() 模板表达式?

【问题讨论】:

  • Ng-init 走上了恐龙的道路。就像你说的,ngOnInit 是放置初始化代码的合适位置,那么他们为什么要保留 ng-init?您在该代码中所做的是尝试将初始化 bind 到一个值,这就是方括号所表示的。但值是一个表达式,正如 Angular 告诉你的那样,它不受支持。
  • 我也非常想念 ng-init,但他已经走了。 RIP
  • @Amleonard 正如问题所说,ng-init 有它的用途,即使它经常被滥用。我知道括号代码绑定了不是所需行为的表达式,这只是我现在拥有的代码。问题是应该如何做才能匹配所需的行为。

标签: javascript angular typescript angular2-template angular2-directives


【解决方案1】:

只是一种解决方法 (Plunker Demo),请参阅 estus 的解决方案答案

init指令:

@Directive({
  selector: '[init]',
  inputs: ['init']
})
export class InitDir {
  init;

  ngOnChanges() {     // `ngOnInit` if you want it to run just once
    if(this.init){
      let iife = function(str){ return eval(str); }.call(this.init[0], this.init[1]);
    }
  }
}

用法:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2 [init]="[this, 'this.name = 1; this.bar();']">Hello {{name}}</h2>
    </div>
  `,
})
export class App {
  constructor() {
    this.name = 'Angular2 (Release Candidate!)'
  }

  bar() {
    alert('Yo Bar!');
  }
}

【讨论】:

  • eval 是邪恶的。假设这将使用 Angular 自己的解析器来实现,这就是它的用途。只是不确定如何。
  • A2中显然有这样的东西,只是因为它做了表达式解析。 @angular/compilercontains a class that is responsible for that。它可能仍然没有记录,但它就在那里。
【解决方案2】:

这可以通过指令来实现:

@Directive({ selector: '[initialize]' })
class InitializeDirective {
  @Output() initialize = new BehaviorSubject();
}

预期用途是:

<div (initialize)="initViaMethodCall(); foo = 'init via assignment'"></div>
<ng-template (initialize)="bar = 'init with no extra markup'"></template>
{{ foo }}
{{ bar }}

【讨论】:

  • 请多于 3 个英文单词。我在代码旁边看到的只有“它是”和“并且”。
  • 它已准备好使用该问题的解决方案,并且代码几乎是自记录的。如果您对此有具体问题,请随时提出。
  • 感谢更新,但我仍然无法正常工作。我有和你一样的.tsdiv: import { Directive, Output } from '@angular/core';从 'rxjs/BehaviorSubject' 导入 { BehaviorSubject }; @Directive({ selector: '[initialize]' }) 导出类 InitDirective { @Output() 初始化 = new BehaviorSubject(100); } AND
    ++++{{ foo}}++++
  • @Output 属性 initializefire/.emit()ing 怎么样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-07
  • 2016-07-01
  • 1970-01-01
  • 2015-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多