简体   繁体   English

Angular自定义指令范围未按预期更新

[英]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? 对我在这里缺少什么的想法?


Update 更新

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM