防止 Ember 观察者在方法中设置 属性 时触发
Prevent Ember observer firing on setting property in method
我在 属性 上设置了一个观察器,在用户输入时 populates/filters 列出公司名称。列表缩小后,用户可以单击列表中的一项。它有点像一个自动完成功能,但有一些不同之处,可以让它在移动设备上按照我想要的方式工作。当用户开始输入时,表单上的所有其他控件都被隐藏当用户选择公司名称时,列表被隐藏并再次显示其他字段,还有一个按钮可以关闭列表并在没有用户的情况下显示其他控件选择一家公司。一切都很完美,除了我无法阻止观察者在用户选择公司时触发,并且在选择公司时 运行s 的操作中设置了具有观察者的公司名称 属性。
这是把手模板的一部分:
{{#each account in accounts}}
<div class="small-12 columns trim"style="background-color:white">
<a href="#" {{action selectAccount account}}>{{account.name}}</a>
</div>
{{/each}}
这里是咖啡脚本控制器的相关代码:
companyName: ''
lastResponse: 0
accounts: null
accountSearchStyle:'display:none'
standardControlStyle: 'display:block'
isSearch: false
searchObserver: Ember.observer('companyName', () ->
Ember.run.debounce(@, @searchAction, 500)
)
# Do a search
searchAction: () ->
@loadPage(@get('companyName'))
loadPage: (companyName) ->
controller = @
if companyName != '' && controller.get('isSearch') == false
@set('accountSearchStyle', 'display:block')
@set('standardControlStyle', 'display:none')
@set('isSearch', 'true')
actions:
cancelAccountSearch: () ->
controller = @
controller.set('selectedAccount', null)
controller.set('accountSearchStyle', 'display:none')
controller.set('standardControlStyle', 'display:block')
controller.set('isSearch', false)
selectAccount: (account) ->
controller = @
controller.set('companyName', account.name)
controller.set('selectedAccount', account)
controller.set('accountSearchStyle', 'display:none')
controller.set('standardControlStyle', 'display:block')
controller.set('isSearch', false)
)
我不太确定发生了什么,我尝试设置另一个标志以禁止其中任何一个 运行ning 并在最后设置该标志,但是不知何故在 selectAccount 的最后一行之后: controller.set('isSearch', false) 是 运行 观察者再次触发并执行它,我最终再次显示搜索控件。所以具体来说,它会回到正常控件一秒钟,然后再次显示搜索控件。我不确定我的代码是否有问题,或者我是否需要找到一种方法来删除观察者并在完成后将其添加回去。几个小时以来,我一直在用头撞它,所以希望有人能为我阐明它。谢谢
我不确定我是否完全理解问题,但你说 "I have been unable to prevent the observer from firing",那么 adding/removing 观察者如何根据需要?
addCompanyNameObserver: function() {
this.addObserver('companyName', this.searchAction);
},
removeCompanyNameObserver: function() {
this.removeObserver('companyName');
},
...
loadPage: function() {
...
this.addCompanyNameObserver();
},
cancelAccountSearch: function() {
...
this.removeCompanyNameObserver();
}
我想我会 post 我发现的解决方案可能不是完美的解决方案,但它确实有效。在实际观察者中添加标志:
searchObserver: Ember.observer('companyName', () ->
if @get('allowSearch')
Ember.run.debounce(@, @searchAction, 500)
)
并在此处设置:
selectAccount: (account) ->
controller = @
@set('allowSearch', false)
controller.set('companyName', account.name)
controller.set('selectedAccount', account)
controller.set('accountSearchStyle', 'display:none')
controller.set('standardControlStyle', 'display:block')
controller.set('isSearch', false)
@set('allowSearch', true)
解决了我的问题。看起来去抖后检查标志是导致问题的原因。
我在 属性 上设置了一个观察器,在用户输入时 populates/filters 列出公司名称。列表缩小后,用户可以单击列表中的一项。它有点像一个自动完成功能,但有一些不同之处,可以让它在移动设备上按照我想要的方式工作。当用户开始输入时,表单上的所有其他控件都被隐藏当用户选择公司名称时,列表被隐藏并再次显示其他字段,还有一个按钮可以关闭列表并在没有用户的情况下显示其他控件选择一家公司。一切都很完美,除了我无法阻止观察者在用户选择公司时触发,并且在选择公司时 运行s 的操作中设置了具有观察者的公司名称 属性。
这是把手模板的一部分:
{{#each account in accounts}}
<div class="small-12 columns trim"style="background-color:white">
<a href="#" {{action selectAccount account}}>{{account.name}}</a>
</div>
{{/each}}
这里是咖啡脚本控制器的相关代码:
companyName: ''
lastResponse: 0
accounts: null
accountSearchStyle:'display:none'
standardControlStyle: 'display:block'
isSearch: false
searchObserver: Ember.observer('companyName', () ->
Ember.run.debounce(@, @searchAction, 500)
)
# Do a search
searchAction: () ->
@loadPage(@get('companyName'))
loadPage: (companyName) ->
controller = @
if companyName != '' && controller.get('isSearch') == false
@set('accountSearchStyle', 'display:block')
@set('standardControlStyle', 'display:none')
@set('isSearch', 'true')
actions:
cancelAccountSearch: () ->
controller = @
controller.set('selectedAccount', null)
controller.set('accountSearchStyle', 'display:none')
controller.set('standardControlStyle', 'display:block')
controller.set('isSearch', false)
selectAccount: (account) ->
controller = @
controller.set('companyName', account.name)
controller.set('selectedAccount', account)
controller.set('accountSearchStyle', 'display:none')
controller.set('standardControlStyle', 'display:block')
controller.set('isSearch', false)
)
我不太确定发生了什么,我尝试设置另一个标志以禁止其中任何一个 运行ning 并在最后设置该标志,但是不知何故在 selectAccount 的最后一行之后: controller.set('isSearch', false) 是 运行 观察者再次触发并执行它,我最终再次显示搜索控件。所以具体来说,它会回到正常控件一秒钟,然后再次显示搜索控件。我不确定我的代码是否有问题,或者我是否需要找到一种方法来删除观察者并在完成后将其添加回去。几个小时以来,我一直在用头撞它,所以希望有人能为我阐明它。谢谢
我不确定我是否完全理解问题,但你说 "I have been unable to prevent the observer from firing",那么 adding/removing 观察者如何根据需要?
addCompanyNameObserver: function() {
this.addObserver('companyName', this.searchAction);
},
removeCompanyNameObserver: function() {
this.removeObserver('companyName');
},
...
loadPage: function() {
...
this.addCompanyNameObserver();
},
cancelAccountSearch: function() {
...
this.removeCompanyNameObserver();
}
我想我会 post 我发现的解决方案可能不是完美的解决方案,但它确实有效。在实际观察者中添加标志:
searchObserver: Ember.observer('companyName', () ->
if @get('allowSearch')
Ember.run.debounce(@, @searchAction, 500)
)
并在此处设置:
selectAccount: (account) ->
controller = @
@set('allowSearch', false)
controller.set('companyName', account.name)
controller.set('selectedAccount', account)
controller.set('accountSearchStyle', 'display:none')
controller.set('standardControlStyle', 'display:block')
controller.set('isSearch', false)
@set('allowSearch', true)
解决了我的问题。看起来去抖后检查标志是导致问题的原因。