2013-05-21 53 views
1

我正在圍繞有狀態對象和Observable商店的MVC模式掙扎。我無法找到什麼時候使用它們,並且混合它們並不像我希望的那麼幹淨。任何啊!瞭解如何管理可觀察的有狀態項目集合?dojo模式 - 何時使用set/watch以及何時使用notify/observe?

如果我做一個item.set(「key」,value),我可以item.watch(「key」,cb),但是然後我的觀察器沒有通知。

我可以做一個item.watch(函數(){state.notify(item,item.id);})總是通知我的觀察者,但如果我觀察呃調用set我得到一個「日期,您必須先觀察()任何數據修改之前的查詢「」我無法調和的錯誤。

我可以通過setTimeout解耦,但它感覺不好。

下面是一些代碼,以顯示我想要:

crudify: function (store, query, crud) 
    { 
     var result; 
     if (!crud) 
     { 
      crud = query; 
      query = store; 
      store = null; 
     } 
     if (store) 
     { 
      query = store.query(query); 
     } 
     result = query.observe(function (row, deleteIndex, insertIndex) 
     { 
      var del = (0 <= deleteIndex), ins = (0 <= insertIndex); 
      !del && ins && crud.c && crud.c(row); 
      del && ins && crud.u && crud.u(row); 
      del && !ins && crud.d && crud.d(row); 
     }, !!crud.u); 
     crud.c && array.forEach(query, crud.c); 
     return result; 
    } 

而且我有一個商店包裝(圖層),這我黑客成碎片試圖得到通知的數據變化的觀察-ERS沒有得到錯誤:

addLayer: function (item) { 
    var that = this; 
    that.store.add(item); 
    item.watch && item.watch(function (name, prior, curr) { 
     if (prior !== curr) { 
      that._queue.push(item); 
      // attempting to eliminate queries which indirectly update the store (can't find source of error) 
      infor.delay(20, "LayerProcessorStoreNotification", function() { 
       that._queue.forEach(function (item) { 
        that.store.notify(item, that.getLayerId(item)); 
       }); 
       that._queue = []; 
      }); 
     } 
    }); 
    return item; 
}, 

延遲的方法是這樣的:

delay: function (timeout, id, callback) 
    { 
     this.delays = this.delays || []; 
     var delay = this.delays[id]; 
     if (delay) 
     { 
      clearTimeout(delay); 
     } 
     delay = setTimeout(callback, timeout); 
     this.delays[id] = delay; 
    }, 

回答

1

我可以做一個item.watch(function(){state.notify(item,item.id); })總是通知我的觀察

我沒有使用這種模式的任何問題,但是......

但如果我的觀察兒通話設置,我得到一個「查詢出來的日期,您必須先觀察()任何數據修改之前的查詢「」我無法調和的錯誤。

你不應該有watch呼叫notify,也有observe呼叫set。選擇一個或另一個。否則,你會爲自己設定一個無限循環的回調。

下面的代碼適用於我。我對crudify函數所作的唯一更改是將array.forEach(query, crud.c)更改爲query.forEach(crud.c)

<script type="text/javascript" src="../javascripts/dojo-release-1.9.3-src/dojo/dojo.js"></script> 
<script type="text/javascript"> 

window.stackoverflow = { 
    crudify: function (store, query, crud) 
    { 
     var result; 
     if (!crud) 
     { 
      crud = query; 
      query = store; 
      store = null; 
     } 
     if (store) 
     { 
      query = store.query(query); 
     } 
     result = query.observe(function (row, deleteIndex, insertIndex) 
     { 
      console.log("Observed"); 
      var del = (0 <= deleteIndex), ins = (0 <= insertIndex); 
      !del && ins && crud.c && crud.c(row); 
      del && ins && crud.u && crud.u(row); 
      del && !ins && crud.d && crud.d(row); 
     }, !!crud.u); 
     crud.c && query.forEach(crud.c); 
     return result; 
    } 
}; 

require([ 
    "dojo/store/Memory", 
    "dojo/store/Observable", 
    "dojo/Stateful", 
    "dojo/_base/json", 
    "dojo/domReady!" 
], function(Memory, Observable, Stateful, dojo){ 

    var store = Observable(new Memory({ data: [] })); 
    var rawData = [ { id: 1, data: "A" }, { id: 2, data: "B" }, { id: 3, data: "C" }] 

    var myQuery = { id : 3 }; 

    rawData.forEach(function (obj, index) { 
     statefulObj = new Stateful(obj); 
     statefulObj.watch(function(name, oldValue, newValue) { 
     console.log("Watched"); 
     store.notify(statefulObj, statefulObj.id); 
     });                
     store.put(statefulObj); 
    }); 

    window.setTimeout(function() { 
     // this directly triggers the observe() callback 
     store.notify(store.get(3), 3); 
    }, 2000); 

    window.setTimeout(function() { 
     // this triggers the watch(), which indirectly triggers observe() through notify() 
     store.get(3).set("data", "Sea?"); 
    }, 4000); 

    window.setTimeout(function() {              
     // this calls no callbacks because it doesn't match the query                
     store.put({ id: 2, data: "Bee" }); 
    }, 6000); 

    window.setTimeout(function() { 
     // this update triggers observe() 
     store.put(new Stateful({ id: 3, data: "See!?!" })); 

     // note that we didn't set up a watch() on this new object (see below) 
    }, 8000); 

    window.setTimeout(function() { 
     // whoops, this doesn't trigger a callback because we forgot to call watch() above 
     store.get(3).set("data", "C4"); 
    }, 10000); 

    window.setTimeout(function() { 
     // but the observe() callback still works 
     store.notify(store.get(3), 3); 
    }, 12000); 

    window.setTimeout(function() { 
     // this deletion triggers observe() 
     store.remove(3); 
    }, 14000); 

    stackoverflow.crudify(
     store, 
     myQuery, 
     { 
      u: function(obj) { 
      console.log("Observed update: obj: " + dojo.toJson(obj)); 
      }, 
      c: function(obj) { 
      console.log("Observed creation: obj: " + dojo.toJson(obj)); 
      }, 
      d: function(obj) { 
      console.log("Observed deletion: obj: " + dojo.toJson(obj)); 
      } 
     }); 
}); 
</script> 
相關問題