gpt4 book ai didi

angularjs - 新 AngularJS ng-ref 指令的陷阱

转载 作者:行者123 更新时间:2023-12-04 08:31:35 28 4
gpt4 key购买 nike

AngularJS V1.7.1 发布 *介绍新 ng-ref directive .虽然这个新指令使用户能够轻松地做某些事情,但我看到了滥用和问题的巨大潜力。
ng-ref属性告诉 AngularJS 在当前范围内发布组件的 Controller 。这对于让诸如音频播放器之类的组件向同级组件公开其 API 非常有用。可以轻松访问其播放和停止控件。
第一个问题是播放器控件是undefined$onInit Controller 的功能。

Initial vm.pl = undefined  <<<< UNDEFINED
Sample = [true,false]
对于依赖于可用数据的代码, 我们如何解决这个问题?
The DEMO

angular.module("app",[])
.controller("ctrl", class ctrl {
constructor() {
console.log("construct")
}
$onInit() {
console.log("onInit", this.pl);
this.initPL = this.pl || 'undefined';
this.sample = this.pl || 'undefined';
this.getSample = () => {
this.sample = `[${this.pl.box1},${this.pl.box2}]`;
}
}
})
.component("player", {
template: `
<fieldset>
$ctrl.box1={{$ctrl.box1}}<br>
$ctrl.box2={{$ctrl.box2}}<br>
<h3>Player</h3>
</fieldset>
`,
controller: class player {
constructor() {
console.log("player",this);
}
$onInit() {
console.log("pl.init", this)
this.box1 = true;
this.box2 = false;
}
},
})
<script src="//unpkg.com/angular@1.7.1/angular.js"></script>
<body ng-app="app" ng-controller="ctrl as vm">
Initial vm.pl = {{vm.initPL}}<br>
Sample = {{vm.sample}}<br>
<button ng-click="vm.getSample()">Get Sample</button>
<br>
<input type="checkbox" ng-model="vm.pl.box1" />
Box1 pl.box1={{vm.pl.box1}}<br>
<input type="checkbox" ng-model="vm.pl.box2" />
Box2 pl.box2={{vm.pl.box2}}<br>
<br>
<player ng-ref="vm.pl"></player>
</body>

最佳答案

获取组件 Controller 的引用并不新鲜,当时的指令允许这样做,这根本不是问题,有必要拥有这样的功能,ng-ref只是您从模板方面执行此操作的助手(与 angular 2+ 相同)。

尽管如此,如果您需要准备好子组件,您应该使用 $postLink()而不是 $onInit . $postLink在组件与其子组件链接后调用,这意味着 ng-ref当它被调用时将准备好。

所以你所要做的就是改变你的onInit像这样:

̶$̶o̶n̶I̶n̶i̶t̶(̶)̶ ̶{̶
$postLink() {
console.log("onInit", this.pl);
this.initPL = this.pl || 'undefined';
this.sample = this.pl || 'undefined';
this.getSample = () => {
this.sample = `[${this.pl.box1},${this.pl.box2}]`;
}
}

$postLink() - Called after this controller's element and its children have been linked. Similar to the post-link function this hook can be used to set up DOM event handlers and do direct DOM manipulation. Note that child elements that contain templateUrl directives will not have been compiled and linked since they are waiting for their template to load asynchronously and their own compilation and linking has been suspended until that occurs. This hook can be considered analogous to the ngAfterViewInit and ngAfterContentInit hooks in Angular. Since the compilation process is rather different in AngularJS there is no direct mapping and care should be taken when upgrading.

Ref.: Understanding Components



完整的工作片段可以在下面找到(我删除了所有 console.log 以使其更清晰):

angular.module("app",[])
.controller("ctrl", class ctrl {
constructor() {
//console.log("construct")
}
$postLink() {
//console.log("onInit", this.pl);
this.initPL = this.pl || 'undefined';
this.sample = this.pl || 'undefined';
this.getSample = () => {
this.sample = `[${this.pl.box1},${this.pl.box2}]`;
}
}
})
.component("player", {
template: `
<fieldset>
$ctrl.box1={{$ctrl.box1}}<br>
$ctrl.box2={{$ctrl.box2}}<br>
</fieldset>
`,
controller: class player {
constructor() {
//console.log("player",this);
}
$onInit() {
//console.log("pl.init", this)
this.box1 = true;
this.box2 = false;
}
},
})
<script src="//unpkg.com/angular@1.7.1/angular.js"></script>
<body ng-app="app" ng-controller="ctrl as vm">
Initial vm.pl = {{vm.initPL}}<br>
Sample = {{vm.sample}}<br>
<button ng-click="vm.getSample()">Get Sample</button>
<br>
<input type="checkbox" ng-model="vm.pl.box1" />
Box1 pl.box1={{vm.pl.box1}}<br>
<input type="checkbox" ng-model="vm.pl.box2" />
Box2 pl.box2={{vm.pl.box2}}<br>
<player ng-ref="vm.pl"></player>
</body>

关于angularjs - 新 AngularJS ng-ref 指令的陷阱,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51715591/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com