Visualizzazione elenco Il metodo getListItemXmlAttributes non riesce con gli elementi di pubblicazione figlio


358

Ho creato una classe JS per popolare i dati di visualizzazione dell'elenco SG / cartelle, quando gli articoli vengono modificati. ( Secondo l'approccio di Jaime) Tutto funziona benissimo quando opero su elementi della pubblicazione in cui sono stati creati.

Es: apro un componente o una pagina e la locked bycolonna personalizzata si aggiorna immediatamente e mostra il mio nome utente.

Tuttavia, quando vado a una pubblicazione figlio e ripeto quel processo, ottengo la finestra che mi chiede se voglio localizzare o modificare l'elemento principale. Se seleziono di modificare la finestra principale, il codice non funziona. Non l'ho ancora capito con il debug iniziale. Chrome sembra ingoiare l'errore, Firefox mi dà un enigma:

Data e ora: 22/06/2012 15:42:54

Errore: eccezione non rilevata: [Eccezione ... "Codice errore restituito componente: 0x80004002 (NS_NOINTERFACE) [nsIWebProgress.DOMWindow]" nsresult: "0x80004002 (NS_NOINTERFACE)" posizione: "Frame JS :: chrome: // browser / content / tabbrowser .xml :: :: line 545 "data: no]

Qualcuno ha qualche idea iniziale? Proverò a pubblicare un po 'di codice più tardi ...

Codice da 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;
};

Codice da 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
Ricevo molto spesso questo messaggio di errore inserendo qualcosa in un DOM illegalmente Qualche aggiornamento su quel codice? Senza questo sarà abbastanza difficile darti una risposta più concreta.
Frank van Puffelen,

4
Fammi vedere come posso pubblicare il codice. è piuttosto grande. Cercherò di tagliare le cose irrilevanti se posso. Non visualizzo alcun errore nei registri sul server CME. Firefox è l'unico browser a dare l'errore. gli altri non mostrano alcun errore ma non popolano le colonne "personalizzate" con i dati.
Warner Soditus,

14
Questo è attualmente irrisolto su Bugzilla . Codice
Mozilla

23
Questo probabilmente non ha nulla a che fare con esso, ma nel tuo inizializzatore di classe per MyCompany.Tridion.RTFExtensions.PageExte stai impostando tutto undefined. Ciò può causare un problema mentre si definisce un attributo e poi si dice che non è definito, il che non ha senso. È meglio impostare il valore iniziale su nullse non si desidera un valore. Come ho detto, probabilmente non importa, a meno che altri codici non stiano verificando la presenza di chiavi definite.
Michael Coxon,

1
Forse questo potrebbe aiutare: w3schools.com/js/js_strict.asp Inoltre, potrebbe non risolvere il problema, ma gli unici undefinedcontrolli che ho visto funzionare sono typeof something === 'undefined'con ===, ==,! =, O! == Inoltre, potresti provare a usare setTimeout per eseguire setXml dopo getOuterXml
Rivenfall

Risposte:


2

[Eccezione ... "Codice errore restituito componente: 0x80004002 (NS_NOINTERFACE) [nsIWebProgress.DOMWindow]"

Ciò significa che non è stata assegnata alcuna finestra all'oggetto nsIWebProgress . Quindi non ha nessun posto dove visualizzare i dati.

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

Questo ti dice quale file è associato a quell'errore. e su quale linea ha commesso un errore.

Ma la vera chiave è l'errore NS_NOINTERFACE. Ciò significa che l'interfaccia non è stata registrata.

Stai usando Type.enableInterface(). È un metodo personalizzato che stai dichiarando altrove? Non lo vedo Potresti volerlo cambiare in.registerInterface()

Vedi questo link Type Class e Type.registerInterface ()

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.