2012-06-22 9 views
358

Utworzono klasę JS do wypełnienia danych widoku listy SG/folderu, gdy elementy zostały zmodyfikowane. (As per Jaime's approach) Wszystko działa świetnie, kiedy działają na przedmioty w publikacji są one utworzone wWidok listy Metoda getListItemXmlAttributes kończy się niepowodzeniem z elementami publikacji podrzędnej

Np.: otworzyć komponent lub stronę i kolumnę zwyczaj locked by natychmiast aktualizacje i pokazuje moją nazwę użytkownika

.

Jednakże, gdy przechodzę do publikacji podrzędnej i powtarzam ten proces, pojawia się okno z pytaniem, czy chcę zlokalizować lub edytować element nadrzędny. Jeśli wybiorę edycję okna nadrzędnego, kod nie będzie działał. Z początkiem debugowania, który wydaje się przełknąć błąd, Firefox daje mi zagadkę:

Timestamp: 6/22/2012 3:42:54 PM

Error: uncaught exception: [Exception... "Component returned failure code: 0x80004002 (NS_NOINTERFACE) [nsIWebProgress.DOMWindow]" nsresult: "0x80004002 (NS_NOINTERFACE)" location: "JS frame :: chrome://browser/content/tabbrowser.xml :: :: line 545" data: no]

Czy ktoś ma jakieś wstępne pomysły? Postaram się pisać jakiś kod później ...

kod z PageEx.js:

Type.registerNamespace("MyCompany.Tridion.RTFExtensions"); 

/* 
* Constructor 
*/ 

MyCompany.Tridion.RTFExtensions.PageEx = function (id) { 
    Type.enableInterface(this, "MyCompany.Tridion.RTFExtensions.PageEx"); 
    this.addInterface("Tridion.ContentManager.Page", [id]); 
    var p = this.properties; 
    p.versionNumberString = undefined; 
    p.modifiedBy = undefined; 
    p.lockedBy = undefined; 
    p.approvalStatus = undefined; 
    p.publishDate = undefined; 
    p.previousVersion = undefined; 
    p.previousApprovalStatus = undefined; 
    p.customModifiedDate = undefined; 
    p.initialModifierUserName = undefined; 
}; 

/* 
* sends the list xml string for the item 
*/ 
MyCompany.Tridion.RTFExtensions.PageEx.prototype.getListItemXmlAttributes = function (customAttributes) { 
    var attribs = {}; 
    $extUtils.getListItemXmlAttributes(customAttributes,this, attribs); 
    return this.callBase("Tridion.ContentManager.Page", "getListItemXmlAttributes", [attribs]); 
}; 


/* 
* This method gets called when an item is opened from list view. node parameter has the information 
* displayed in the list view as attributes. We are getting cutom data extender column information 
* from this xml node and storing it in this class member for returning it from getListItemXmlAttributes method 
*/ 
MyCompany.Tridion.RTFExtensions.PageEx.prototype.setDataFromList = function (node, parentId, timeStamp) { 
    $extUtils.setDataFromList(node,parentId,timeStamp,this); 
    this.callBase("Tridion.ContentManager.Page", "setDataFromList", [node, parentId, timeStamp]); 
}; 

/* 
* Gets item icon 
*/ 
MyCompany.Tridion.RTFExtensions.PageEx.prototype.getItemIcon = function() { 
    var icon = this.callBase(this.defaultBase, "getItemIcon"); 
    return icon; 
}; 

kod z utils.js:

// reloads the list view for the given id (used in list view data refresh when JS cant get the required data without reloading) 
MyCompany.Tridion.RTFExtensions.Utilities.reloadListView = function (listTcmId) { 
    var registry = $models.getListsRegistry(); 
    for(var key in registry) 
    { 
     var entry = $models.getItem(registry[key]); 
     if (entry && entry.getParentId() == listTcmId) 
     { 
      entry.unload(); 
      return true; 
     } 
    } 
    return false; 
} 

/* 
* This method gets called when an item is opened from list view. node parameter has the information 
* displayed in the list view as attributes. We are getting cutom data extender column information 
* from this xml node and storing it in this class member for returning it from getListItemXmlAttributes method 
*/ 
MyCompany.Tridion.RTFExtensions.Utilities.setDataFromList = function (node, parentId, timeStamp, itemClicked) { 
    var p = itemClicked.properties; 

    if (!timeStamp || timeStamp > itemClicked.getTimeStamp()) { 
     var tmp; 
     if (tmp = node.getAttribute('Version')) { 
      p.versionNumberString = tmp; 
      p.previousVersion = tmp; 
     } 
     if (tmp = node.getAttribute('ModifiedBy')) { 
      p.modifiedBy = tmp; 
      p.initialModifierUserName = tmp; 
     } 
     if (tmp = node.getAttribute('LockedBy')) { 
      p.lockedBy = tmp; 
     } 
     if (tmp = node.getAttribute('ApprovalStatus')) { 
      p.approvalStatus = tmp; 
      p.previousApprovalStatus = tmp; 
     } 
     if (tmp = node.getAttribute('PublishDate')) { 
      p.publishDate = tmp; 
     } 
     if (p.customModifiedDate === undefined) { 
      if (tmp = node.getAttribute('Modified')) { 
       p.customModifiedDate = tmp; 
      } 
     } 
    } 
} 

/* 
* sends the list xml string for the item in the list view. 
*/ 
MyCompany.Tridion.RTFExtensions.Utilities.getListItemXmlAttributes = function (customAttributes, listViewObject,attribs) { 
    var p = listViewObject.properties; 
    $extUtils.getListViewItemLockedByName(p,listViewObject); 

    if (customAttributes) { 
     for (var attr in customAttributes) { 
      attribs[attr] = customAttributes[attr]; 
     } 
    } 

    attribs["Version"] = $extUtils.getListViewItemUpdatedVersion(p,listViewObject); 
    //modified name has to come after the version update... 
    $extUtils.getListViewItemModifiedByName(p,listViewObject); 
    attribs["ApprovalStatus"] = $extUtils.getListViewItemApprovalStatus(p,listViewObject); 
    attribs["PublishDate"] = $extUtils.getListViewItemPublishDate(p,listViewObject); 

    //set default values 
    if (p.versionNumberString != undefined) { 
     var iResult = p.versionNumberString.localeCompare(p.previousVersion); 
     if (p.previousVersion === undefined || iResult > 0) { 
      //it's been updated! 
      p.previousVersion = p.versionNumberString; 
      p.previousApprovalStatus = p.approvalStatus; 

      //also need to update modified date 
      p.customModifiedDate = $extUtils.getListViewItemUpdatedModifiedDate(p,listViewObject); 
      p.initialModifierUserName = p.modifiedBy; 
     } 

    } 
    attribs["Modified"] = p.customModifiedDate; 
    attribs["LockedBy"] = p.lockedBy; 
    attribs["ModifiedBy"] = p.modifiedBy; 

}; 

/* 
* This method sets the property of the Revisor owner on the item in the list view. however, if it's not the current user 
* we have no way to look that up in JS so we have to reload the list view. 
*/ 
MyCompany.Tridion.RTFExtensions.Utilities.getListViewItemModifiedByName = function (p,listViewObject) { 
    var p = listViewObject.properties; 
    var xmlDoc = listViewObject.getXmlDocument(); 
    if (xmlDoc) { 
     //modifier should always exist... 
     var modifierId = $xml.getInnerText(xmlDoc, "/tcm:*/tcm:Info/tcm:VersionInfo/tcm:Revisor/@xlink:title"); 
     if (modifierId != undefined) { 
      var u = Tridion.UI.UserSettings.getJsonUserSettings(true); 
      if (modifierId == u.User.Data.Name) { 
       var strDescription = u.User.Data.Description.split('('); 
       p.modifiedBy = strDescription[0]; 
       return; 
      } else { 
       //we're in trouble... 
       //let's hope it's the initial modifier we had... 
       if (p.previousVersion == p.versionNumberString) { 
        //whew... 
        p.modifiedBy = p.initialModifierUserName; 
        return; 
       } 

       if (!$extUtils.reloadListView(listViewObject.getOrganizationalItemId())) { 
        //hrm. something failed on the reload? not sure what else to do: 
        p.modifiedBy = modifierId; 
       } 
      } 
     } else { 
      //shouldn't ever happen. 
      p.modifiedBy = ""; 
      return; 
     } 
    } 

}; 

/* 
* This method sets the property of the lock owner on the item in the list view. however, if it's not the current user 
* we have no way to look that up in JS so we have to reload the list view. 
*/ 
MyCompany.Tridion.RTFExtensions.Utilities.getListViewItemLockedByName = function (p,listViewObject) { 
    var xmlDoc = listViewObject.getXmlDocument(); 
    if (xmlDoc) { 
     //this will be user id. no sense getting tcmid... can't look it up without async call 
     var lockedUserId = $xml.getInnerText(xmlDoc, "/tcm:*/tcm:Info/tcm:VersionInfo/tcm:ItemLock/tcm:User/@xlink:title"); 
     if (lockedUserId != undefined) { 
      //see if it's the current user. most likely... 
      var u = Tridion.UI.UserSettings.getJsonUserSettings(true); 
      if (lockedUserId == u.User.Data.Name) { 
       var strDescription = u.User.Data.Description.split('('); 
       p.lockedBy = strDescription[0]; 
       return; 
      } 
      //it's not the current user. no synch way to do what we want, plus the JS call doesn't get the workflow version anyway. refresh the parent view 
      if (!$extUtils.reloadListView(listViewObject.getOrganizationalItemId())) { 
       //hrm. something failed on the reload? not sure what else to do: 
       p.lockedBy = lockedUserId; 
      } 
     } else { 
      //clear it out since there's no lock owner 
      p.lockedBy = ""; 
     } 
    } 
}; 

/* 
* Gets the ApprovalStatus from the item 
* This makes absolutely no sense... but for some reason the approval status gets wiped out when this method 
* enters. so I had to use a "previous approval status" variable to maintain it. no idea why. I don't see anything 
* else that should be touching it... but clearly something clears it out. 
*/ 
MyCompany.Tridion.RTFExtensions.Utilities.getListViewItemApprovalStatus = function (p,listViewObject) { 
    //check if the item has actually been modified. 
    if (p.versionNumberString != p.previousVersion) { 
     var xmlDoc = listViewObject.getXmlDocument(); 
     if (xmlDoc) { 
      p.approvalStatus = $xml.getInnerText(xmlDoc, "/tcm:*/tcm:Info/tcm:Data/tcm:ApprovalStatus/@xlink:title"); 
     } 
    } else { 
     p.approvalStatus = p.previousApprovalStatus; 
    } 
    if (p.approvalStatus === undefined || p.approvalStatus.toUpperCase() == 'UNAPPROVED') { 
     var foo = p.approvalStatus; 
     p.approvalStatus = 'WIP'; 
    } 
    return p.approvalStatus; 
}; 


/* 
* Gets the PublishDate from the item list view 
*/ 
MyCompany.Tridion.RTFExtensions.Utilities.getListViewItemPublishDate = function (p,listViewObject) { 
    //modification won't alter publish date. 
    var p = listViewObject.properties; 
    return p.publishDate; 
}; 


/* 
* get the modified date for the workflow version, overwrite OOB since that uses last major version 
*/ 
MyCompany.Tridion.RTFExtensions.Utilities.getListViewItemUpdatedModifiedDate = function (p,listViewObject) { 
    var xmlDoc = listViewObject.getXmlDocument(); 
    var modDate = $xml.getInnerText(xmlDoc, "/tcm:*/tcm:Info/tcm:VersionInfo/tcm:RevisionDate"); 
    return modDate; 
} 


/* 
* Gets the updated Version information from the item 
*/ 
MyCompany.Tridion.RTFExtensions.Utilities.getListViewItemUpdatedVersion = function (p,listViewObject) { 
    var p = listViewObject.properties; 
    var xmlDoc = listViewObject.getXmlDocument(); 
    var newVersionString = undefined; 
    if (xmlDoc) { 
     newVersionString = String.format("{0}.{1}", $xml.getInnerText(xmlDoc, "/tcm:*/tcm:Info/tcm:VersionInfo/tcm:Version"), $xml.getInnerText(xmlDoc, "/tcm:*/tcm:Info/tcm:VersionInfo/tcm:Revision")); 
    } 
    if (newVersionString != undefined) { 
     //want to ensure we're getting a LATER version than we had (because it will try to load the non-workflow version afterwards... 
     var iResult = newVersionString.localeCompare(p.previousVersion); 
     if (p.previousVersion === undefined || iResult > 0) { 
      p.versionNumberString = newVersionString; 
     } else { 
      p.versionNumberString = p.previousVersion; 
     } 
    } else { 
     p.versionNumberString = p.previousVersion; 
    } 
    return p.versionNumberString; 
}; 



function launchPopup(winURL, winName, winFeatures, winObj) { 
    // this will hold our opened window 
    var theWin; 
    // first check to see if the window already exists 
    if (winObj != null) { 
     // the window has already been created, but did the user close it? 
     // if so, then reopen it. Otherwise make it the active window. 
     if (!winObj.closed) { 
      winObj.focus(); 
      return winObj; 
     } 
     // otherwise fall through to the code below to re-open the window 
    } 
    // if we get here, then the window hasn't been created yet, or it 
    // was closed by the user. 
    theWin = window.open(winURL, winName, winFeatures); 
    return theWin; 
} 

var $extUtils = MyCompany.Tridion.RTFExtensions.Utilities; 
+11

mam taki komunikat o błędzie najczęściej od wkładając coś do DOM nielegalnie każdej aktualizacji na tym kodem? Bez tego trudno będzie udzielić bardziej konkretnej odpowiedzi. –

+4

Zobaczę, jak mogę opublikować kod. to dość duże. Postaram się wykończyć nieistotne rzeczy, jeśli mogę. Nie dostaję żadnych błędów w dziennikach na serwerze CME. Firefox jest jedyną przeglądarką, która podaje błąd. pozostałe nie pokazują żadnego błędu, po prostu nie wypełniają "niestandardowych" kolumn danymi. –

+0

@FrankvanPuffelen, jakieś myśli? Jestem zaskoczony ... próbowałem oglądać rzeczy z debuggerem JS i nie widziałem, co tu się dzieje. wszelkie pomysły będą najbardziej cenione. –

Odpowiedz

2

[Exception... "Component returned failure code: 0x80004002 (NS_NOINTERFACE) [nsIWebProgress.DOMWindow]"

Oznacza to, że nie nie było okna przypisanego do obiektu nsIWebProgress. Więc nie ma gdzie wyświetlać danych.

nsresult: "0x80004002 (NS_NOINTERFACE)" location: "JS frame :: chrome://browser/content/tabbrowser.xml :: :: line 545" data: no]

Informuje o tym, który plik jest powiązany z tym błędem. i w jakiej linii była błędna.

Ale prawdziwym kluczem jest błąd NS_NOINTERFACE. Co oznacza, że ​​interfejs nie został zarejestrowany.

Używasz Type.enableInterface(). Czy jest to niestandardowa metoda, którą deklarujesz gdzie indziej? Nie widzę tego. Może chcesz to zmienić, aby .registerInterface()

Zobacz ten link Type Class i Type.registerInterface()