[英]Angular custom directive scope not updating as expected
I have a few directives being used on a page in my TypeScript application, and each have their own controllers to manage their own scope. 我在TypeScript应用程序的页面上使用了一些指令,每个指令都有自己的控制器来管理自己的范围。 Everything has been working quite smoothly until this really strange bug.
一切都很顺利,直到这个奇怪的错误。
I have a keypad
directive being used in a payment
directive which is called by my order
controller. 我在
payment
指令中使用了一个keypad
指令,该指令由我的order
控制器调用。 I'm going to keep my code samples minimal for simplicity. 为简单起见,我将保留我的代码示例。
My payment
directive has a controller which has a constructor that has: 我的
payment
指令有一个控制器,它有一个构造函数,它具有:
$scope.vm = this;
I use this pattern very frequently. 我经常使用这种模式。 My
payment
directive also has a function keypadOnChange()
that is invoked from the keypad
directive. 我的
payment
指令还有一个函数keypadOnChange()
,它是从keypad
指令调用的。
// In the payment directive:
public keypadOnChange(keypadDirective: IKeypadDirectiveController): void {
console.log("keypad is changed");
console.log(keypadDirective.selection);
this.manualTenderInputValue = Number(keypadDirective.selectionToString());
console.log(this.manualTenderInputValue);
}
The thing worth noting here is that the console
displays everything I expect it to at exactly the right time. 值得注意的是,
console
会在恰当的时间显示我期望的所有内容。
My template for the payment
directive contains: 我的
payment
指令模板包含:
<div ng-show="vm.keypadIsVisible" class="square_keypad">
<div class="white"
keypad
onchange="vm.keypadOnChange"></div>
</div>
<div class="item manual-tender-input-field item-white item-small-padding"
ng-click="vm.toggleKeypadVisibility()">
{{ vm.manualTenderInputValue }}
</div>
Again, the thing worth noting is that all functions and behavior are working as expected -- including vm.keypadIsVisible
which is changed in a similar way to vm.manualTenderInputValue
. 同样值得注意的是,所有函数和行为都按预期工作 - 包括
vm.keypadIsVisible
,它以与vm.manualTenderInputValue
类似的方式vm.manualTenderInputValue
。
The problem is that vm.manualTenderInputValue
is not getting updated. 问题是
vm.manualTenderInputValue
没有得到更新。 It displays the appropriate value on page load, and I can console.log()
its value when it's changed, and it is correct, but I can't get the {{ }}
to update. 它显示在页面加载相应的价值,我可以
console.log()
它的价值时,它的变化,它是正确的,但我不能让{{ }}
更新。
Any thoughts on what I'm missing here? 对我在这里缺少什么的想法?
My keypad
directive handles a change event, so it can tell anyone listening about the change and they can do as they please with the data. 我的
keypad
指令处理更改事件,因此它可以告诉任何人听取更改,他们可以随心所欲地处理数据。 It looks like this (and spoiler: here in lies the problem...) 它看起来像这样(和扰流板:这里存在问题......)
My keypad directive has a controller that has these noteworthy lines: 我的键盘指令有一个控制器,有这些值得注意的线:
// a public variable:
public onChange: any = null;
// in the constructor:
$scope.$watch("onchange", (v) => { this.onChange = v; });
// in a function invoked by ng-click:
public selectNumber(digit: string, domId?: string): void {
// ... some other stuff not relevant ...
this.triggerOnChange();
}
// the triggerOnChange in the keypad directive controller:
public triggerOnChange(): void {
if (this.onChange) {
this.onChange(this);
}
}
Now, back to my payment
which had a template that had a line looked like: 现在,回到我的
payment
,其中有一个模板有一行看起来像:
<div class="white"
keypad
onchange="vm.keypadOnChange"></div>
And the payment
directive controller has the keypadOnChange
function included in the original post. 并且
payment
指令控制器具有包含在原始帖子中的keypadOnChange
功能。 I threw in a console.log(this)
and discovered that in that context, this
was referring to the instance of the keypad
directive controller. 我扔了一个
console.log(this)
现在那个上下文中, this
是指keypad
指令控制器的实例。 And that is the problem! 这就是问题所在!
But... how do I fix this ? 但是......我该如何解决这个问题呢? (no pun intended)
(没有双关语)
How do I make it so that when keypadOnChange
is invoked on the payment
controller it still has the right this
context (and can therefore update the scope)? 如何让这个当
keypadOnChange
是在调用payment
控制器,它仍然有正确的this
方面(因此可以更新范围)?
One final note, I'm using this keypad
directive elsewhere and didn't run into this issue. 最后一点,我在其他地方使用这个
keypad
指令并没有遇到这个问题。
What solved my problem was ensuring that I could maintain the this
context for the payment
directive controller. 什么解决了我的问题是确保我可以维护
payment
指令控制器的this
上下文。
My payment
controller constructor ended up including: 我的
payment
控制器构造函数最终包括:
this.keypadChange = this.onKeypadChange.bind(this);
While onKeypadChange()
remained the same: 虽然
onKeypadChange()
保持不变:
public keypadOnChange(keypadDirective: IKeypadDirectiveController): void {
// is now referring to the instance of the controller, NOT the keypad directive:
console.log(this);
this.manualTenderInputValue = Number(keypadDirective.selectionToString());
}
Finally, the template that calls the keypad
directive now looks like: 最后,调用
keypad
指令的模板现在看起来像:
<div class="white" keypad onchange="vm.keypadChange"></div>
Based on comments and suggestions, I'll likely be changing some of my attribute names to avoid confusion, but this solution answers my original question. 基于评论和建议,我可能会更改一些属性名称以避免混淆,但此解决方案可以回答我原来的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.