รายการมุมมองวิธีการ getListItemXmlAttributes ล้มเหลวด้วยรายการสิ่งพิมพ์เด็ก


358

ฉันสร้างคลาส JS เพื่อเติมข้อมูลมุมมองรายการ SG / Folder เมื่อมีการแก้ไขรายการ ( ตามแนวทางของ Jaime) ทุกอย่างใช้งานได้ดีเมื่อฉันทำงานกับรายการในสิ่งพิมพ์ที่พวกเขาสร้างขึ้น

ตัวอย่าง:ฉันเปิดส่วนประกอบหรือหน้าและlocked byคอลัมน์ที่กำหนดเองจะอัปเดตและแสดงชื่อผู้ใช้ของฉันทันที

อย่างไรก็ตามเมื่อฉันไปที่สิ่งพิมพ์ย่อยและทำซ้ำขั้นตอนนั้นฉันจะได้รับหน้าต่างถามว่าฉันต้องการแปลหรือแก้ไขรายการหลัก หากฉันเลือกที่จะแก้ไขหน้าต่างหลักรหัสจะไม่ทำงาน ฉันยังไม่ได้คิดออกเลยด้วยการดีบักเริ่มต้น Chrome ดูเหมือนจะกลืนข้อผิดพลาด Firefox ให้ความลับแก่ฉัน:

เวลา: 6/22/2012 3:42:54 PM

ข้อผิดพลาด: ข้อยกเว้นที่ไม่ได้ตรวจสอบ: [ข้อยกเว้น ... "คอมโพเนนต์ส่งคืนรหัสความล้มเหลว: 0x80004002 (NS_NOINTERFACE) [nsIWebProgress.DOMWindow]" nsresult: "0x80004002 (NS_NOINTERFACE)" ที่ตั้ง: "JS frame :: chrome: // browser / content / tabbrowser .xml :: :: ข้อมูลบรรทัด 545 ": ไม่]

ไม่มีใครมีความคิดเริ่มต้นหรือไม่? ฉันจะลองโพสต์รหัสในภายหลังใน ...

รหัสจาก 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;
};

รหัสจาก 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
ฉันได้รับข้อความแสดงข้อผิดพลาดดังกล่าวบ่อยที่สุดจากการแทรกบางสิ่งบางอย่างลงใน DOM อย่างผิดกฎหมายการอัปเดตของรหัสนั้นหรือไม่ หากปราศจากสิ่งนั้นมันจะค่อนข้างยากที่จะให้คำตอบที่เป็นรูปธรรมมากขึ้น
Frank van Puffelen

4
ให้ฉันดูว่าฉันจะโพสต์รหัสได้อย่างไร มันค่อนข้างใหญ่ ฉันจะพยายามตัดสิ่งที่ไม่เกี่ยวข้องออกหากทำได้ ฉันไม่ได้รับข้อผิดพลาดใด ๆ ในบันทึกบนเซิร์ฟเวอร์ CME Firefox เป็นเบราว์เซอร์เดียวที่ให้ข้อผิดพลาด คนอื่น ๆ ไม่แสดงข้อผิดพลาดเพียง แต่ไม่เติมคอลัมน์ "กำหนดเอง" ด้วยข้อมูล
Warner Soditus

14
สิ่งนี้ไม่ได้รับการแก้ไขในBugzilla ในปัจจุบัน รหัส mozilla ที่เกี่ยวข้อง
davidcondrey

23
นี้น่าจะมีอะไรจะทำอย่างไรกับมัน แต่ใน initialiser ชั้นเรียนของคุณสำหรับคุณกำลังตั้งทุกอย่างเพื่อMyCompany.Tridion.RTFExtensions.PageEx undefinedสิ่งนี้อาจทำให้เกิดปัญหาในขณะที่คุณกำหนดแอตทริบิวต์จากนั้นบอกว่ามันไม่ได้กำหนดซึ่งไม่สมเหตุสมผล มันเป็นการดีกว่าที่จะตั้งค่าเริ่มต้นเป็นnullถ้าคุณไม่ต้องการค่า ที่ผมกล่าวนี้อาจจะไม่ได้เรื่องเว้นแต่รหัสอื่น ๆ คือการตรวจสอบสำหรับคีย์ที่กำหนดไว้ ..
ไมเคิล Coxon

1
บางทีนี่อาจช่วยได้: w3schools.com/js/js_strict.aspนอกจากนี้มันอาจไม่สามารถแก้ไขปัญหาของคุณได้ แต่การundefinedตรวจสอบเพียงอย่างเดียวที่ฉันเห็นว่าทำงานtypeof something === 'undefined'กับ ===, ==,! = หรือ! == นอกจากนี้ คุณสามารถลองใช้ setTimeout เพื่อดำเนินการ setXml หลังจาก getOuterXml
Rivenfall

คำตอบ:


2

[ข้อยกเว้น ... "คอมโพเนนต์ส่งคืนรหัสความล้มเหลว: 0x80004002 (NS_NOINTERFACE) [nsIWebProgress.DOMWindow]"

ซึ่งหมายความว่าไม่มีหน้าต่างที่กำหนดให้กับวัตถุnsIWebProgress ดังนั้นจึงไม่มีที่แสดงข้อมูล

nsresult: ตำแหน่ง "0x80004002 (NS_NOINTERFACE)": "เฟรม JS :: chrome: //browser/content/tabbrowser.xml :: :: line 545" data: no]

นี่เป็นการบอกคุณว่าไฟล์ใดที่เกี่ยวข้องกับข้อผิดพลาดนั้น และสิ่งที่บรรทัดมัน faulted on

แต่คีย์จริงคือข้อผิดพลาด NS_NOINTERFACE ซึ่งหมายความว่าอินเทอร์เฟซยังไม่ได้ลงทะเบียน

Type.enableInterface()คุณกำลังใช้ นั่นเป็นวิธีการที่กำหนดเองที่คุณจะประกาศที่อื่นหรือไม่? ฉันไม่เห็นมัน คุณอาจต้องการเปลี่ยนสิ่งนั้นเป็น.registerInterface()

ดูลิงค์นี้พิมพ์ Class และ Type.registerInterface ()

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.