문제

내가 사용하 knockout(KO)에서 내 MVC 프로젝트입니다.내가 만드는 MVC 모델(위 그리드)서버에게 전달합니다.에서 보기 직렬화과로 전환 ENG 모델을 사용하여(ko.매핑)에 사용되는 바인딩.는 바인딩은 다음 HTML 에서 사용되는 그리드 생성.

이것은 어떻게 내 MVC grid 모델은 다음과 같이 차례로 변환되면 해당 코여 모델 ko.매핑:

public class GridModel
    {
        /// <summary>
        /// Grid body for the grid.
        /// </summary>
        public GridBodyModel GridBodyModel { get; set; }

        /// <summary>
        /// Grid context.
        /// </summary>
        public GridContext GridContext { get; set; }

        /// <summary>
        /// Grid header for the grid.
        /// </summary>
        public GridHeaderModel GridHeader { get; set; }
    }

public class GridBodyModel
    {
        /// <summary>
        /// List of grid body rows.
        /// </summary>
        public IList<GridRowModel> Rows { get; set; }
    }


public class GridContext
    {
        /// <summary>
        /// Total number of pages. Read-only.
        /// </summary>
        public int TotalPages{ get; set; }
    }

public class GridHeaderModel
    {
        /// <summary>
        /// List of grid header cells.
        /// </summary>
        public IList<GridHeaderCellModel> Cells { get; set; }
    }

그것은 명확한 메인 모델 등 GridModel 은 다음과 같은 클래스가 존재하는 같은 속성:

GridBodyModel:는 행 목록에서 렌더링될 수 있는 격자체.

GridContext:는 전체 페이지 수로 제공합니다.그것은 다른 속성을 뿐만 아니라 하지만 그의 범위는 이 논의한다.

GridHeaderModel:목록을 가지고 있는 세포의 수에 표시되는 헤더의 자리를 차지하고 있습니다.

나는 이 스크립트를 실행할에 신선한니다.

$(document).ready(function () {
        // Apply Knockout view model bindings when document is in ready state.
        ko.applyBindings(Global_GridKOModel, document.getElementById("gridMainContainer"));
    });

// Serialize the server model object. It will be used to create observable model.
Global_GridKOModel = ko.mapping.fromJS (<%= DataFormatter.SerializeToJson(Model) %>);

Global_GridKOModel 글로벌 javascript 변수입니다.모델 은 MVC 격자 모델에서 오는 서버입니다.

사용자가 수행할 수 있는 추가 검색 페이지에서 다시합니다.나는이 게시하여 새로운 검색 기준을 통해 Ajax.이 게시물에 대한 새로운 MVC 모델을 만들은 다시 전송으로 Ajax 를 응답합니다.이 새로운 MVC 모델은 다음 단순히 사용을 업데이트 Global_GridKOModel 를 사용하여 ko.매핑을 차례로 새로 고쳐 그리드(새로운 데이터)에 건설되었다 이전에 신선한니다.이것은 어떻게 내가 그것을 하고 있다.

$.ajax({
        url: destUrl,
        data: dataToSend
        success: function (result) {
            ko.mapping.fromJS(result, Global_GridKOModel);
        },
        error: function (request, textStatus, errorThrown) {
            alert(request.statusText);
        }
    });

모든 것이 잘 작동하 제외하고 다음과 같은 경우에.

Ajax 요청이 이루어지는 결과가 반환되지 않 즉 GridBodyModel 및 GridHeaderModel null 모델 GridModel.는 시간 격자 바로는 기록이 없이 발견되었습니다.이것은 올바른 것입니다.이런 일이 발생하여 다음과 같은 HTML 구속력이 있습니다.

<!-- When no record is found. -->
<div data-bind="ifnot: GridContext.GridPager.TotalPages() > 0">
    No record(s) were found.
</div>

<!-- This is actual grid table container. This is binded when records are found -->
<div data-bind="if: GridContext.TotalPages() > 0">

Grid construction happens here

</div>

지금 이 경우 다른 Ajax 요청이지만 이번에는 레코드가 반환됩(내가 확인 응답을 가진 방화하고 그것은 확인 하는 기록은 참으로 반환).이 시간 그리드 건설 점에서 일어나는 다양한 현저한 배열에 액세스할 수 있습니다.예를 들어,구출에 대한 격자는 다음의 조각 HTML 바인딩을 썼다.

<td data-bind="attr:{colspan: GridHeader.Cells().length }">

이번 코 발생 다음과 같은 오류가에서 볼 수 있는 방화.

구문 분석할 수 없습니다.메시지:TypeError:GridHeader.세포 기능은 없습니다;인 값:attr:{colspan:GridHeader.세포().길이}

그것은 작동하도록 긴 레코드가 반환되지만 그 후에 기록이 없는 돌 위에서 설명했다.하시기 바랍 GridHeader 었 null 에서 이전의 경우 응답이 레코드가 반환됩니다.냄새가 나는 뭔가 물고기에 ko.매핑을 사용합니다.가 있다고 생각 어떤 문제에 매핑하는 동안 현저 배열입니다.

그래서 무엇인가는 내가 하고 있지?누구나요?

을 주시기 바랍 대한 설명 요청이 있는 경우 언급하지 않는 것을 명확하다.

미리 감사드립니다.

도움이 되었습니까?

해결책

동작의 실제 이유는 원래 GridHeader가 JavaScript 객체이지만 GridHeader 속성에 대해 NULL로 반환 호출 매핑을 할 때 NULL 값으로 볼 수 있으며 향후 업데이트는 여전히 관찰 할 수 있습니다.

해결 방법은 (하나 선택) :

  1. 하위 모델의 널 값을 리턴하지 마십시오 (대신 빈 객체를 반환합니다). 선호하는 방법이라고 생각합니다.
  2. 또는 - 맵을 호출하기 전에 global_gridkomodel.gridheader= null; (이것은 Update GridHeader가 Observable이 아닌 경우)
  3. 또는 - 맵핑 후에 전화하십시오 global_gridkomodel.gridheader= ko.unwrapobservable (global_gridkomodel.gridheader);

    다음과 같은 동작에 대한 전체 설명은 아래 코드 (jsfiddle - http : // jsfiddle)입니다. net / nickolsky / zrbul / 9 / )

    console.log('step1');
    var vm = ko.mapping.fromJS({ body: { children: [ 1, 2, 3]} });
    console.log(vm.body.children()[1]); //prints 2
    
    console.log('step2');
    ko.mapping.fromJS({ body: { children: [ 4, 5, 6]} }, vm);
    console.log(vm.body.children()[1]); //prints 5
    
    console.log('step3');
    //after next call, vm.body is no longer variable - it is now observable
    ko.mapping.fromJS({ body: null }, vm);
    console.log(vm.body); //prints observable
    console.log(vm.body()); //prints null
    
    console.log('step4');
    //and it will remain observable for next call
    ko.mapping.fromJS({ body: { children: [ 7, 8, 9]} }, vm);
    console.log(vm.body().children()[1]); //prints 8
    console.log(vm.body().children().length); //prints 3
    console.log(vm.body); //prints observable function body
    console.log(vm.body()); //prints object
    
    //workaround for null issue - we can reset it to be null instead of null observable
    //and it will get original behavior
    vm.body = null;
    console.log('step5');    
    ko.mapping.fromJS({ body: { children: [ 7, 8, 9]} }, vm);
    console.log(vm.body.children()[1]); //prints 8 - body is no longer observable again
    ​
    
    .

    Mapping Plugin의 디자인 문제처럼 보입니다. 자식 ViewModel 속성을위한 매핑을 사용자 정의하는 방법을 찾을 수 없었습니다. 내부 콘텐츠가 관찰 할 수없는, 불행한 atelly).

다른 팁

나는 그것을 알아 냈다.실제로 이는 매우 기본적인 실수가 있었습니다.었다 액세스하려는 배열을 설정한 후 그것은 null 입니다.나는 그것을 설명하는 방법.

때 결과를 반환되었는 시간 GridHeaderModel 고 명령 세포에서 그것은 정의,즉지 않은 null 입니다.는 시간 ko.매핑을 변환 할 수 있었 모델을 만들고 모델 arrary 니다.그러나 때 어떤 ajax 요청되었다는 점에서 noo 결과를 반환하고 GridHeaderModel 었 null,분명히 명령 세포 null too.는 시간 ko.매핑을 했는 동일한,EN 모델 업데이트로 설정 GridHeaderModel null 너무 및 관찰할 수 있는 배열 세포 안에 없었던 존재하는대로 좋은 null 입니다.지금을 만들었을 때 다른 아약스 요청 일부 레코드가 반환되었습니다.매핑을 관찰할 수 있는 배포하는 존재하지 않았(또는 설정하 null)코 모델 클라이언트에서,그것은 실패했습니다.는 경우에는 대신 ajax 그것은 신선한 페이지로드는 모든 것을 일했다.그래서 솔루션을 반환하지 어떤 열거(는 사람들 얻을 것으로 변환을 관찰할 수 배)초기화되지 않은 클라이언트을 위한 코 모델 업데이트합니다.따라서는 레코드가 반환될 수 있는지 확인했는 GridHeaderModel 이 null 이 아니고 또한 있는지 명령 세포는 초기화되지 않았다는 포함된 모든 요소입니다.이 고정된 문제입니다.

이 문제가 될 수 있습 explaied 다음과 같은 예입니다.

public class Demo
{
    public IList<string> DemoArray;
}

public class DemoUser
{
    public void UseDemo()
        {
            var demoInstance = new Demo();
            demoInstance.DemoArray.Add("First Element");
        }
}

여기에서 UseDemo()메소드가 초기화된 클래스의 인스턴스지 명령 DemoArray 남아 un-초기화됩니다.그렇게 할 때 우리는 그것을 액세스하려고 런타임 예외가 발생합니다.이것은 무슨 일이 일어나고 있었을 수도 있습니다.에서 먼저 ajax 응답 내가 설정을 관찰할 수 있는 배열에 null,즉un-초기화한 다음에 다음 ajax 반응하려고 노력했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top