一位采访者问我:
什么是Observer
和Observable
我们何时应该使用它们?
我不知道这些术语的,所以,当我回到家,开始对谷歌搜索Observer
和Observable
,我发现来自不同资源的一些要点:
1)
Observable
是一个类,Observer
是一个接口.2)
Observable
该类维护一个Observer
s 列表.3)当一个
Observable
对象被更新时,它会调用update()
每个Observer
s 的方法来通知它,它被改变了.
我找到了这个例子:
import java.util.Observable;
import java.util.Observer;
class MessageBoard extends Observable
{
public void changeMessage(String message)
{
setChanged();
notifyObservers(message);
}
}
class Student implements Observer
{
@Override
public void update(Observable o, Object arg)
{
System.out.println("Message board changed: " + arg);
}
}
public class MessageBoardTest
{
public static void main(String[] args)
{ …
Run Code Online (Sandbox Code Playgroud) 收到第一个结果后,如何删除观察者?下面是我尝试过的两种代码方式,但即使我已经删除了观察者,它们也都会继续接收更新.
Observer observer = new Observer<DownloadItem>() {
@Override
public void onChanged(@Nullable DownloadItem downloadItem) {
if(downloadItem!= null) {
DownloadManager.this.downloadManagerListener.onDownloadManagerFailed(null, "this item already exists");
return;
}
startDownload();
model.getDownloadByContentId(contentId).removeObservers((AppCompatActivity)context);
}
};
model.getDownloadByContentId(contentId).observeForever(observer);
Run Code Online (Sandbox Code Playgroud)
model.getDownloadByContentId(contentId).observe((AppCompatActivity)context, downloadItem-> {
if(downloadItem!= null) {
this.downloadManagerListener.onDownloadManagerFailed(null, "this item already exists");
return;
}
startDownload();
model.getDownloadByContentId(contentId).removeObserver(downloadItem-> {});
} );
Run Code Online (Sandbox Code Playgroud) 我在类中声明了var,如下所示:
@NSManaged var isFavorite: Bool
Run Code Online (Sandbox Code Playgroud)
我想宣布一个属性观察者,非常类似于下面的那个.
var organization: String {
didSet { postNotificationWithName( "newData" ) }
}
Run Code Online (Sandbox Code Playgroud)
但是,Swift告诉我,NSManaged
不允许在vars 上拥有财产观察员.有什么方法可以为我的isFavorite
变量实现这样的功能或类似的功能吗?
我的用户模型有一个观察者。在我的观察者->创建的事件中我有一些代码。
public function created(User $user)
{
sendEmail();
}
Run Code Online (Sandbox Code Playgroud)
因此,我们的想法是,当创建用户时,系统将向用户发送帐户已创建的电子邮件通知。
问题:当数据库进行播种时,它还会调用此方法“已创建”并向用户(位于种子中)发送电子邮件通知。所以,我的问题是,我如何检查,可能在这个“创建”方法中,目前 Laravel 正在播种数据 -> 不发送电子邮件或不运行“创建”观察者方法。
尝试谷歌,找到了一些东西,但工作不正确。就像是YourModel::flushEventListeners();
文档说observeEventType:withBlock
如果您不再需要它,您需要调用以删除观察者.
我见过它被称为内容的样本ViewDidDisAppear
.我也发现了一些称为此方法的Obj-C代码deinit
,这在Swift中是不必要的.
但是,在我的简单应用程序中,只要我在应用程序中,就希望数据同步.如果是这种情况,我是否必须打电话observeEventType:withBlock
?
我检查了Firebase网站上的Chat-Swift示例代码,但没有找到observeEventType:withBlock
.
这是否意味着不打电话observeEventType:withBlock
:.如果我希望观察者在应用程序使用时打开?
谢谢.
UPDATE
感谢Jay和David.我认为在ViewWillAppear中观察并在ViewDidDisappear中删除它是有意义的.
但是,我使用observeEventType来监视节点的任何值更改,如果有任何更新UI.如果我把它放在ViewWillAppear中:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
ref.observeEventType(.Value, withBlock: { snap in {
// **update UI if there is any Value change**
})
}
Run Code Online (Sandbox Code Playgroud)
将其放入的问题viewWillAppear
是,无论值是否发生变化,每次出现视图时都会调用它.因此,每次返回视图时都会下载快照并刷新我的UI.这会适得其反.
我也试过ChildAdded
/ ChildRemoved
,但它只返回最后一个节点,而不是我的ref的路径:
例如,如果我添加到ref/child1/child2/child3/value,ChildAdded
则只返回child3/value.
所以,如果我必须观察价值,似乎把它放进去ViewDidLoad
更好?通过这种方式,它可以在加载视图时获取一次快照,并且只要有更改就会重复,但只是因为视图出现而无法获取快照.
有时候我们需要动态地将自定义元素添加到上下文中.然后:
插入的聚合物可以接收绑定到上下文中的另一个属性的一些属性,因此它可以相应地改变.
在聚合物0.5处,我们可以使用PathObserver将属性绑定到最近添加的组件的上下文属性.但是,我没有在聚合物1.0中找到解决方法或等效物.
我创建了一个0.5的示例,并为1.0创建了相同的示例.请参阅下面的注射聚合物代码.此外,您还可以看到完整的plunker示例,以便清晰.
Ej 0.5:
<polymer-element name="main-context">
<template>
<one-element foo="{{foo}}"></one-element>
<div id="dynamic">
</div>
</template>
<script>
Polymer({
domReady: function() {
// injecting component into polymer and binding foo via PathObserver
var el = document.createElement("another-element");
el.bind("foo", new PathObserver(this,"foo"));
this.$.dynamic.appendChild(el);
}
});
</script>
</polymer-element>
Run Code Online (Sandbox Code Playgroud)
请参阅完整的plunkr示例:http://plnkr.co/edit/2Aj3LcGP1t42xo1eq5V6?p = preview
Ej 1.0:
<dom-module id="main-context">
<template>
<one-element foo="{{foo}}"></one-element>
<div id="dynamic">
</div>
</template>
</dom-module>
<script>
Polymer({
is: "main-context",
ready: function() {
// injecting component into polymer and binding foo via PathObserver
var el = document.createElement("another-element"); …
Run Code Online (Sandbox Code Playgroud) 我RecyclerView
用它实现了Custom Adapter
如下
全球宣言如下
private LinearLayoutManager linearLayoutManager;
private int pastVisibleItems, visibleItemCount, totalItemCount;
private CustomRecyclerViewAdapter customRecyclerViewAdapter;
Run Code Online (Sandbox Code Playgroud)
首先,我在onCreate()
方法内部创建了适配器实例,其中包含Empty Array
并将其设置为recyclerView
linearLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
Utility.ItemDecorationConst);
recyclerView.addItemDecoration(dividerItemDecoration);
customRecyclerViewAdapter = new CustomRecyclerViewAdapter(getActivity());
recyclerView.setAdapter(customRecyclerViewAdapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
visibleItemCount = linearLayoutManager.getChildCount();
totalItemCount = linearLayoutManager.getItemCount();
pastVisibleItems = linearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
loading = false;
customRecyclerViewAdapter.addProgressBarEntry();
controller.getNextPage(PublisherAppContainerFragment.this);
}
} …
Run Code Online (Sandbox Code Playgroud) android observers notifydatasetchanged recycler-adapter android-recyclerview
我在结帐时有一些代码,我在会话中设置了一个密钥,如果在结帐时将该密钥设置为false,我需要将它们发送回结算页面.我有它的代码,但我也不能拥有通常在观察者之后运行的任何代码,因为它会调用第三方服务并因为会话中缺少此密钥而返回错误
这是我的代码,我有我想要的一切,但我需要立即发生的响应,并且在调度的事件行被发送后只发送回发送回浏览器的响应.
public function checkForOrdKey(Varien_Event_Observer $observer)
{
$controllerAction = $observer->getControllerAction();
$request = $controllerAction->getRequest();
$controllerName = $request->getControllerName();
$stepData = $this->_getCheckoutSession()->getStepData();
$ordKeyRemoved = $this->_getCheckoutSession()->getOrdKeyRemoved();
// if it is the checkout onepage controller or inventory controller don't do anything
if (isset($controllerName) && $controllerName === "onepage" && $stepData['shipping']['complete'] && $ordKeyRemoved) {
$this->_getCheckoutSession()->setStepData('shipping', 'complete', false);
$result['goto_section'] = 'billing';
Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
$this->_getCheckoutSession()->setOrdKeyRemoved(false);
}
}
Run Code Online (Sandbox Code Playgroud) 我已经在catalog_product_save_after
事件上创建了一个观察者,但它似乎是在运行该applyAllRulesOnProduct()
方法的catalogrule观察者之前调用的.applyAllRulesOnProduct()
跑步后我需要打电话给我.如何选择这些观察员的顺序?
当为模型观察者使用单独的类时,我应该在哪里注册观察者?文档说要打电话,User::observe(new UserObserver);
但我不知道最好的地方在哪里.