结构指令的上下文未更新

时间:2017-08-19 16:13:38

标签: angular angular2-template

我创建了一个带上下文的结构指令。

var object = {
         propriety1 : "value1",
         propriety2 : "value2",
         propriety3 : "value3"
}
     
for (var x in object) {
  console.log(object.x);
}
     
console.log(object.propriety1);

这就是我使用它的方式。

@Directive({selector: '[myDir]'})
export class MyDir implements OnInit {
  constructor(private templateRef: TemplateRef<any>,
              private viewContainerRef: ViewContainerRef,
  ) { }

  public context = {$implicit: false}

  ngOnInit() {
    this.viewContainerRef.createEmbeddedView(this.templateRef, this.context)
  }
}

模板已正确安装到视图中,<pre *myDir="let context">Context: {{ context | json}}</pre> 按预期存在。

但是,如果我尝试更改上下文,则不会反映在视图中。从ngTemplateOutlet spec from the Angular repo来看,看起来应该在上下文发生变化时进行更新。 我的代码中是否有错误,或者我是否误解了规范?

我也试过注入CR并手动触发变化检测,但它没有用。在我的实际情况中,更改应该是在可观察的订阅上触发,该订阅会监听鼠标事件,但这是一个简单间隔的演示。

Context: false

虽然Observable .interval(500) .map((_, i) => i % 2 == 0) .takeUntil(this.destroy$) .subscribe(context => { this.context = {$implicit: context} console.log('Context is now', this.context.$implicit) }) 确实更改,并且控制台中显示的更改 ,但视图不会更新。 Here's a demo on StackBlitz

我已经添加取消订阅销毁,因为否则闪电战在一些重新加载后发疯。还添加了一个测试observable,它只是一个与AppComponent间隔半秒的简单计数器,与指令无关。这只是一个完整性检查应用程序正在运行,CD循环通常正在整个应用程序正常运行。我不在任何地方使用OnPush。

1 个答案:

答案 0 :(得分:3)

Javascript是非常引人入胜的语言。

让我们考虑以下代码:

let view: any = {};
function detectChanges() {
  console.log(view.context);
}

function createEmbeddedView(context) {
  view.context = context;
}

let context = { x: false };
createEmbeddedView(context);

detectChanges(); // prints { x: false }

当我们创建context并将其传递给createEmbeddedView函数时。

现在让我们改变context。我们将做两个选择:

1)改变自己

context = { x: true };

detectChanges(); // prints { x: false }

2)更改INTERNALS

context.x = true;

detectChanges(); // prints { x: true} Hooray!!!

我们可以看到我们的输出在第一种情况下没有改变,而在第二种情况下工作。这是因为在javascript中我们传递了对象by sharing

它是一种特定的传值。如果我们更改参数本身,它将不会对函数内部的项目产生任何影响。但是如果我们改变一些属性,那么它将改变项目。

因此,对于您的情况,您可以更改您的上下文,如:

this.context.$implicit = context;

https://stackblitz.com/edit/so-context-question-a4n5yx?file=app%2Fapp.component.ts