하위 공개 항목으로 목록보기 getListItemXmlAttributes 메소드가 실패 함


358

항목이 수정 될 때 SG / 폴더 목록보기 데이터를 채우기 위해 JS 클래스를 작성했습니다. ( Jaime의 접근 방식에 따라) 내가 작성한 발행물의 항목을 조작 할 때 모든 것이 훌륭하게 작동합니다.

예 : 구성 요소 나 페이지를 열면 사용자 정의 locked by열이 즉시 업데이트되고 사용자 이름이 표시됩니다.

그러나 자식 게시로 이동하여 해당 프로세스를 반복하면 부모 항목을 현지화하거나 편집 할 것인지 묻는 창이 나타납니다. 부모 창을 편집하도록 선택하면 코드가 작동하지 않습니다. 초기 디버깅으로 아직 파악하지 못했습니다. 크롬은 오류를 삼키는 것처럼 보이며 Firefox는 나에게 암호를 제공합니다.

타임 스탬프 : 2012-06-22 오후 3:42:54

오류 : catch되지 않은 예외 : [Exception ... "구성 요소가 실패 코드를 반환했습니다 : 0x80004002 (NS_NOINTERFACE) [nsIWebProgress.DOMWindow]"nsresult : "0x80004002 (NS_NOINTERFACE)"위치 : "JS 프레임 :: 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는 오류를 발생시키는 유일한 브라우저입니다. 다른 것들은 오류가 없다는 것을 보여 주지만 단지 "custom"열을 데이터로 채우지 마십시오.
워너 소디 투스

14
이것은 현재 Bugzilla 에서 해결되지 않았습니다 . 관련 mozilla 코드
davidcondrey

23
이것은 아마도 그것과 관련이 없지만 수업 초기 MyCompany.Tridion.RTFExtensions.PageEx에는 모든 것을로 설정하고 undefined있습니다. 속성을 정의한 후 정의되지 않았다고 말하면 문제가 발생할 수 있습니다. 값을 null원하지 않으면 초기 값을 설정하는 것이 좋습니다 . 내가 말했듯이 다른 코드가 정의 된 키를 확인하지 않는 한 이것은 중요하지 않을 것입니다.
Michael Coxon

1
어쩌면 이것이 도움이 될 수 있습니다 : w3schools.com/js/js_strict.asp 또한 문제를 해결하지 못할 수도 있지만 undefined제가 확인한 유일한 점검 사항은 typeof something === 'undefined'===, ==,! = 또는! == 당신은 getOuterXml 후 setXml을 실행하는 데에서는 setTimeout을 사용하려고 할 수 있습니다
Rivenfall

답변:


2

[예외 ... "구성 요소에서 오류 코드를 반환했습니다 : 0x80004002 (NS_NOINTERFACE) [nsIWebProgress.DOMWindow]"

이는 nsIWebProgress 객체에 할당 된 창이 없음을 의미 합니다. 따라서 데이터를 표시 할 위치가 없습니다.

nsresult : "0x80004002 (NS_NOINTERFACE)"위치 : "JS 프레임 :: chrome : //browser/content/tabbrowser.xml :: :: 줄 545"데이터 : 아니요]

이것은 해당 오류와 관련된 파일을 알려줍니다. 그리고 어떤 라인에 결함이 있는지.

그러나 실제 키는 NS_NOINTERFACE 오류입니다. 인터페이스가 등록되지 않았 음을 의미합니다.

사용하고 Type.enableInterface()있습니다. 다른 곳에서 선언하는 사용자 정의 방법입니까? 나는 그것을 보지 못한다. 그걸로 바꾸고 싶을 수도 있습니다..registerInterface()

이 링크를 참조하십시오 Type Class and Type.registerInterface ()

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.