Chế độ xem danh sách getListItemXmlAttribution không thành công với các mục xuất bản con


358

Tôi đã tạo một lớp JS để điền dữ liệu xem danh sách SG / Thư mục, khi các mục được sửa đổi. ( Theo cách tiếp cận của Jaime) Mọi thứ hoạt động tuyệt vời khi tôi vận hành trên các vật phẩm trong ấn phẩm mà chúng được tạo ra.

Ví dụ: Tôi mở một thành phần hoặc trang và locked bycột tùy chỉnh cập nhật ngay lập tức và hiển thị tên người dùng của tôi.

Tuy nhiên, khi tôi đến một ấn phẩm con và lặp lại quá trình đó, tôi nhận được cửa sổ hỏi tôi có muốn bản địa hóa hoặc chỉnh sửa mục cha mẹ không. Nếu tôi chọn chỉnh sửa cửa sổ cha, mã không hoạt động. Tôi đã không hoàn toàn tìm ra nó với gỡ lỗi ban đầu. Chrome dường như nuốt lỗi, Firefox mang đến cho tôi một mật mã:

Dấu thời gian: 22/12/2012 3:42:54 PM

Lỗi: không ngoại lệ: [Ngoại lệ ... "Thành phần trả về mã lỗi: 0x80004002 (NS_NOINTERFACE) [nsIWebProTHER.DOMWindow]" nsresult: "0x80004002 (NS_NOINTERFACE)" vị trí: " .xml :: :: dòng 545 "dữ liệu: không]

Có ai có ý tưởng ban đầu không? Tôi sẽ cố gắng đăng một số mã sau này trên ...

Mã từ 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;
};

Mã từ 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
Tôi nhận được thông báo lỗi như vậy thường xuyên nhất từ ​​việc chèn một cái gì đó vào DOM bất hợp pháp Bất kỳ cập nhật nào về mã đó? Nếu không có điều đó sẽ khá khó khăn để cung cấp cho bạn một câu trả lời cụ thể hơn.
Frank van Puffelen

4
Hãy để tôi xem làm thế nào tôi có thể gửi mã. nó khá to Tôi sẽ cố gắng cắt bỏ những thứ không liên quan nếu tôi có thể. Tôi không nhận được bất kỳ lỗi nào trong nhật ký trên máy chủ CME. Firefox là trình duyệt duy nhất đưa ra lỗi. những cái khác cho thấy không có lỗi chỉ là không điền vào các cột "tùy chỉnh" với dữ liệu.
Warner Soditus

14
Điều này hiện chưa được giải quyết trên Bugzilla . Mã mozilla có liên quan
davidcondrey

23
Điều này có lẽ không có gì để làm với nó, nhưng trong trình khởi tạo lớp của bạn cho MyCompany.Tridion.RTFExtensions.PageExbạn đang thiết lập mọi thứ undefined. Điều này có thể gây ra sự cố khi bạn đang xác định một thuộc tính sau đó nói với nó rằng nó không được xác định - điều này không có ý nghĩa. Tốt hơn là đặt giá trị ban đầu thành nullnếu bạn không muốn một giá trị. Như tôi đã nói điều này có lẽ không thành vấn đề, trừ khi các mã khác đang kiểm tra các khóa được xác định ..
Michael Coxon

1
Có lẽ điều này có thể giúp: w3schools.com/js/js_strict.asp Ngoài ra, nó có thể không khắc phục vấn đề của bạn, nhưng undefinedkiểm tra duy nhất tôi thấy công việc là typeof something === 'undefined'với ===, == ,! =, Hoặc! == Ngoài ra, bạn có thể thử sử dụng setTimeout để thực thi setXml sau getOuterXml
Rivenfall

Câu trả lời:


2

[Ngoại lệ ... "Thành phần trả về mã lỗi: 0x80004002 (NS_NOINTERFACE) [nsIWebProTHER.DOMWindow]"

Điều này có nghĩa là không có cửa sổ nào được gán cho đối tượng nsIWebProTHER . Vì vậy, nó không có nơi nào để hiển thị dữ liệu.

nsresult: "0x80004002 (NS_NOINTERFACE)" vị trí: "Khung JS :: chrome: //browser/content/tabbrowser.xml :: :: dòng 545" dữ liệu: không]

Điều này cho bạn biết tập tin nào liên quan đến lỗi đó. và dòng nào nó bị lỗi trên.

Nhưng khóa thực sự là lỗi NS_NOINTERFACE. Có nghĩa là giao diện chưa được đăng ký.

Bạn đang sử dụng Type.enableInterface(). Đó có phải là một phương thức tùy chỉnh mà bạn đang khai báo ở một nơi khác không? Tôi không thấy nó. Bạn có thể muốn thay đổi điều đó thành.registerInterface()

Xem liên kết này Loại ClassType.registerInterface ()

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.