Making sure my extended lists always show “current” data?

前端 未结 4 1866
我寻月下人不归
我寻月下人不归 2021-01-05 03:41

When you create a Data Extender for a CME list – for instance to add a column for the Schema as in this example – it all works fine and dandy whenever you do actions that fo

4条回答
  •  無奈伤痛
    2021-01-05 04:32

    Well, Jaime correctly described how CME updates changed items in Lists. But I want to add some additional information on how List controls, domain model List and Items are interact with each other. This might help you building your own extension with similar functionality.

    Most of the domain model List items inherit from Tridion.ContentManager.ListTcmItems class. On the moment when any List item, based on mentioned class, is loaded it will be registered in Lists Registry (and un-registered when the List is unloaded). This will allow Model to use registered Lists as source of static data for Items and to update changed Items data in these Lists.

    Update Item static data

    For example, we have loaded ListCategories and there is only one Category in the List:

    var pub = $models.getItem("tcm:0-1-1");
    var list = pub.getListCategories();
    list.load();
    
    // After list is loaded
    list.getXml();
    

    That getXml() returns an XML like (simplified):

    
        
    
    

    After that, if you try to get some static data for Category "Keys" it will be already set:

    var category = $models.getItem("tcm:1-4-512");
    category.isLoaded();         // return false
    category.isStaticLoaded();   // return false
    category.getTitle();         // return undefined
    category.getStaticTitle();   // return "Keys"!
    

    That is possible because $models.getItem call will do two things: it will return an existing (or create a new) domain model object and call $models.updateItemData method with it. This method call will go through all registered Lists in the Lists Registry and for all Lists whose TimeStamp bigger than Item's Last Update TimeStamp will call list.updateItemData with the model object.

    The updateItemData method will check if the passed Item is in the list and if it is, then the Item will be updated with the static data that is available from the List.

    Updating data of changed Items in the List

    When a domain model Item is modified (updated, removed, created new) one of these methods is called:

    • $models.itemUpdated
    • $models.itemRemoved

    These methods will go through the Lists in Lists Registry and call list.itemUpdated (or list.itemRemoved). These methods will check is passed Item is contained in their List and if so they will update the List xml from the Item data.

    For that purpose there is a getListItemXmlNode method in the Tridion.ContentManager.Item class. This method will build List xml node based on the array of attributes, provided by getListItemXmlAttributes method on the Item. That's what Jaime mentioned in his answer.

    If the List xml was updated, one of these events will be fired on List object:

    • itemadd
    • itemupdate
    • itemremove

    Listening to these events on a List object in your view will allow you to timely update your List Control.

    So if you want this mechanism to work with your extension, stick to these rules:

    • If you are creating new domain model List object - it should inherit Tridion.ContentManager.ListTcmItems class or it should implement the getId(), itemUpdated(item), itemsUpdated(item), itemRemoved(item) and updateItemData(item) methods
    • If you want to see changes in List control - attach handlers to corresponding events on the domain model List object and update your List control
    • If you are creating new domain model Item - it should inherit Tridion.ContentManager.Item class and you should improve getListItemXmlAttributes method to return correct array of attributes for the List

提交回复
热议问题