2013-08-01 23 views
0

使用DurandalJS我創建了一個顯示特定數據的Web應用程序。這些數據通過BreezeJS收集,並從durandalJS框架的激活函數中調用。回發時數據不會顯示在頁面上

當我第一次進入頁面A時,所有數據都正確加載。然後,當我通過A頁上的鏈接轉到頁面B,然後通過鏈接返回頁面B時,我可以看到數據已加載到我的knockoutJS observablearrays中,但未顯示!

當第一次加載時頁面上有多個可觀察數組像A1,B2和C3,當我在web應用程序上瀏覽並返回具有可觀察數的特定頁面時,它們全部正確加載A1和C3是加載和B2不!另一個時刻A1和B2和C3沒有顯示。這是非常隨機的!

當我按CTRL + F5時,一切正常加載。這與DurandalJS的框架有什麼關係?有誰知道如何解決這個問題?

我試過到目前爲止: 使用defferred 使用禁用因此其屬性都以正確的方式清理,使他們能夠在激活

沒有填寫迄今爲止圖書館的

版本:

  • KnockoutJS:2.3.0
  • BreezeJS:1.4.0
  • 杜蘭德alJS:1.2.0

這些是我包含的庫的當前版本。他們最近更新,這將解決問題,但它沒有。

這裏是我的DataService這是一個Singleton:

var DataserviceClass = (function() { 
    function DataserviceClass() { 
     this._isSaving = false; 
     this.suspendItemSave = false; 
     this.ds = new breeze.DataService({ 
      serviceName: "api/data", 
      hasServerMetadata: true 
     }); 
     this.manager = new breeze.EntityManager({dataService: this.ds}); 
     this.metadataStore = this.manager.metadataStore; 
     this.entityQuery = new breeze.EntityQuery(); 
     this.getMetadataStore = function() { 
      return this.metadataStore; 
     }; 

     this.getExportData = function() { 
      return this.manager.exportEntities(); 
     }; 


     this.getAllRows = function (functionName, expand) { 
      if (expand == null || expand == undefined) { 
       this.entityQuery = breeze.EntityQuery.from(functionName); 
      } else { 
       this.entityQuery = breeze.EntityQuery.from(functionName). 
                 expand(expand); 
      } 
      return this.manager.executeQuery(this.entityQuery); 
     }; 

     this.getSpecificID = function (functionName, idName, id) { 
      this.entityQuery = breeze.EntityQuery.from(functionName).where(idName, "==", id); 
      return this.manager.executeQuery(this.entityQuery); 
     }; 


     this.createT = function (initialValues, entity) { 
      return this.manager.createEntity(entity, initialValues); 
     }; 

     this.saveChanges = function (suppressLogIfNothingToSave) { 
      if (this.manager.hasChanges()) { 
       if (this._isSaving) { 
        setTimeout(this.saveChanges, 50); 
        return; 
       } 
       return this.manager.saveChanges().then(this.saveSucceeded).fail(this.saveFailed).fin(this.saveFinished); 
      } else if (!suppressLogIfNothingToSave) { 
      } 
     }; 

     this.saveSucceeded = function (saveResult) { 
      this._isSaving = false; 
     }; 
     this.saveFailed = function (error) { 
     }; 
     this.saveFinished = function() { 
      this._isSaving = false; 
     }; 
    }  
    var instance; 
    return { 
     getInstance: function() { 
      if (instance == null) { 
       instance = new DataserviceClass(); 
       instance.constructor = null; 
      } 
      return instance; 
     } 
    }; 
})(); 

像估計的網頁,它被稱爲如下,這是視圖模型:

define(function (require) { 
    var router = require('durandal/plugins/router'), 
     app = require('durandal/app'), 
     system = require('durandal/system'), 
     addmemo = require('viewmodels/modals/addMemo'), 
     container = require('viewmodels/modals/container'), 
     memo = require('viewmodels/modals/memo'), 
     dataservice = require('services/dataservice'), 
     logger = require('services/logger'), 
     addRepairOrderLine = require('viewmodels/modals/addRepairOrderLine'), 
     repairorderline = require('viewmodels/modals/RepairOrderLine'), 
     customerModal = require('viewmodels/modals/customer'), 
     currentLoggedInEmployee = ko.observable(), 
     memos = ko.observableArray([]), 
     deferred = $.Deferred(), 
     repairorderlines = ko.observableArray([]), 
     tasksToMonitor = [], 
     isLoading = ko.observable(false), 
     suspendItemSave = false, 
     rightParameters = true, 
     notDone = true, 
     hourscost = ko.observable(0.0), 
     materialcost = ko.observable(0.0), 
     grandtotal = ko.observable(0.0), 
     currentRepairOrderID = -1, 
     currentOrderID = -1, 
     currentOrder = ko.observable(), 
     currentRepairOrder = ko.observable(null), 
     currentContainerID = -1, 
     currentCustomer = ko.observable(null), 
     currentBillingCustomer = ko.observable(null), 
     currentContainer = ko.observable(null), 
     showElementFade = function(elem) { if (elem.nodeType === 1) $(elem).hide().slideDown(); }, 
     hideElementFade = function(elem) { if (elem.nodeType === 1) $(elem).slideUp(function() { $(elem).remove(); }); }; 


    //This function is called ones, only when the page hasn't loaded yet! 
    function init() { 
     dataservice = DataserviceClass.getInstance(); 

     dataservice.getSpecificID('Employees', 'EmployeeID', 1).then(function (data) { 
      currentLoggedInEmployee = data.results[0]; 
     }).fail(function(data) { 
      logger.logError('Error fetching the current logged in employee!', null, null, true); 
     }); 
    } 
    init(); 

    return { 
     displayName: 'Estimating page', 
     router: router, 
     currentCustomer: currentCustomer, 
     currentContainer: currentContainer, 
     currentRepairOrder: currentRepairOrder, 
     currentBillingCustomer: currentBillingCustomer, 
     memos: memos, 
     repairorderlines: repairorderlines, 
     isLoading: isLoading, 
     hourscost: hourscost, 
     materialcost: materialcost, 
     grandtotal: grandtotal, 
     activate: function (Context) { 
      currentRepairOrder(null); 
      currentBillingCustomer(null); 
      rightParameters = true; 
      //also need to check if ids exist in DB!! 
      if (!Context.hasOwnProperty("orderid") || isNaN(Context.orderid) || 
       !Context.hasOwnProperty("repairorderid") || isNaN(Context.repairorderid)) { 
       rightParameters = false; 
       system.log('Not all the right parameters!'); 
       router.navigateTo('#/error'); //eventueel parameters meegeven! 
       return; 
      } 

      //set id's 
      currentRepairOrderID = Context.repairorderid; 
      currentOrderID = Context.orderid; 
      tasksToMonitor = []; //empty the task function 


      breeze.EntityQuery.from("Orders") 
       .where("OrderID", "==", parseInt(Context.orderid)) 
       .expand("Customer, Customer.PostCountry, Customer.VisitCountry, Container, Container.ContainerManufacturer, Container.ContainerType, Container.Owner") 
       .using(dataservice.manager) 
       .execute().then(function (data) { 
        if (data.results.length < 1) { 
         system.log('Not all the right parameters!'); 
         rightParameters = false; 
         router.navigateTo('#/error'); //eventueel parameters meegeven! 
         return; 
        } 
        //extendItem(data.results[0]); 
        currentOrder(data.results[0]); 

        var customer = data.results[0].Customer(); 
        //extendItem(customer); 
        currentCustomer(customer); 

        var container = data.results[0].Container(); 
        //extendItem(container); 
        currentContainer(container); 
       }).fail(function (data) { 
        logger.logError('Error fetching the current Order!', null, null, true); 
       }).fin(function() { 

       }); 
      //In the future this will be calling the order 2 


      breeze.EntityQuery.from("RepairOrders") 
       .where("RepairOrderID", "==", parseInt(Context.repairorderid)) 
       .expand("BillingCustomer, BillingCustomer.PostCountry, BillingCustomer.VisitCountry") 
       .using(dataservice.manager) 
       .execute().then(function (data) { 
        currentRepairOrder(data.results[0]); 
        currentBillingCustomer(data.results[0].BillingCustomer()); 
       }).fail(function (data) { 
        logger.logError('Error fetching current repairorder!', null, null, true); 
       }).fin(function() { 
        //first set the value to true (loading done) 
        //Call the global function to check each process 
        tasksToMonitor[0][1] = true; 
        checkTasks(); 
       }); 

      //by adding this if statements the data is only loaded if it hasn't been loaded yet! 
      //voor nu alle memos van alle medewerkers, later alleen die van betreffende? 

      if (memos._latestValue.length == 0) { 
       breeze.EntityQuery.from("Memos") 
        .where("RepairOrderID", "==", parseInt(Context.repairorderid)) 
        //.expand("Customer, Container, Container.ContainerManufacturer, Container.ContainerType") 
        .expand("Employee") 
        .using(dataservice.manager) 
        .execute().then(function (data) { 
         data.results.forEach(function (item) { 
          extendItem(item); 
          memos.push(new memo(item)); 
         }); 
         system.log("Initialization succesfull!"); 
         logger.logSuccess('Initialization succesfull', null, 'estimatepage', true); 
        }).fail(function (data) { 
         logger.logError('Error fetching memos!', null, null, true); 
        }).fin(function() { 
         tasksToMonitor[1][1] = true; 
         checkTasks(); 
        }); 
      } 


      if (repairorderlines._latestValue.length == 0) { 
       breeze.EntityQuery.from("RepairOrderLines") 
        .where("RepairOrderID", "==", parseInt(Context.repairorderid)) 
        .expand("Customer") 
        .using(dataservice.manager) 
        .execute().then(function (data) { 
         data.results.forEach(function (item) { 
          extendItem(item); 
          repairorderlines.push(new repairorderline(item)); 
         }); 
         updateFinance(); 
         // 
        }).fail(function (data) { 
         logger.logError('Error fetching repairorderlines!', null, null, true); 
        }).fin(function() { 
         tasksToMonitor[2][1] = true; 
         checkTasks(); 
         // deferred.resolve(); 
        }); 
      } 

      logger.log("Estimating page started!", null, "estimagepage", true); 
      return deferred.promise(); 
      //return; 
     }, 
     canDeactivate: function() { 
      if (rightParameters && notDone) { 
       return app.showMessage('Are you sure you want to leave this page and stop estimating?', 'Navigate', ['Yes', 'No']); 
      } else { 
       return true; 
      } 
     }, 
     deactivate: function() { 
      //remove everything here! I mean remove the data in the models! Everything is already saved ;) 
      memos.removeAll(); 
      repairorderlines.removeAll(); 

      currentRepairOrderID = -1; 
      currentOrderID = -1; 
      currentOrder(null); 
      currentRepairOrder(null); 
      currentContainerID = -1; 
      currentCustomer(null); 
      currentBillingCustomer(null); 
      currentContainer(null); 
     }, 
     showCustomerModal: function(selectedCustomer,element) { 
      app.showModal(new customerModal(selectedCustomer)).then(function() { 

      }).fail(function() { 

      }); 
     }, 
     showContainerModal: function() { 
      app.showModal(new container(currentContainer, currentOrder())).then(function (result) { 

      }).fail(function(result) { 

      }); 
     }, 
     cancelEstimation: function() { 
      app.showMessage('Do you want to delete this estimation?', 'Delete estimate', ['Yes', 'No']).then(function (resultMessageBox) { 
       if (resultMessageBox == "Yes") { 

       } 
       //else if no the user just clicked OK and everything is saved 
      }); 
     }, 

     selectedRepairOrderLine: function (selectedRepairOrderLine, element) { 
      app.showModal(selectedRepairOrderLine).then(function (result) { 
       if (result) { 
        app.showMessage('Do you want to delete this RepairOrderLine?', 'Delete RepairOrderLine', ['Yes', 'No']).then(function (resultMessageBox) { 
         if (resultMessageBox == "Yes") { 
          repairorderlines.remove(selectedRepairOrderLine); 
          selectedRepairOrderLine.RepairOrderLineEntity._latestValue.entityAspect.setDeleted(); 
          dataservice.saveChanges(); 
          updateFinance(); //dont remove this one its called ! 
          logger.logSuccess('Repairline deleted successfully', null, null, true); 
         } 
         //else if, no the user just clicked OK and everything is saved so also updatefinance is called a couple of line further 
        }); 
       } 
       updateFinance(); //But we must update the finance because things could have been changed! 
      }).fail(function() { 
       logger.logError('Something went wrong selecting the memo!', null, 'estimatepage', true); 
      }); 
     }, 
     selectedMemo: function (selectedMemo, element) { 
       app.showMessage('Do you want to delete this memo?', 'Delete memo', ['Yes', 'No']).then(function (resultMessageBox) { 
        if (resultMessageBox == "Yes") { 
         memos.remove(selectedMemo); 
         selectedMemo.MemoEntity._latestValue.entityAspect.setDeleted(); 
         dataservice.saveChanges(); 
        } 
        //else if no the user just clicked OK and everything is saved 
      }).fail(function() { 
       logger.logError('Something went wrong selecting the memo!', null, 'estimatepage', true); 
      }); 
     }, 
    }; 
}); 

這是隨之而來的觀點:

<div class="row-fluid"> 
    <div class="span6"> 
     <!-- Estimate Information --> 
     <!-- Estimate HEADER --> 
     <div class="fiftypx" data-bind='with: currentContainer'> 
      <span class="main_title">ESTIMATE</span> 
      <span class="main_container_number" data-bind="text: ContainerNumber"></span> 
     </div> 
     <!-- Estimate Propertys --> 
     <div class="row-fluid"> 
      <div class="span6"> 
       <fieldset> 
        <div class="estimate_info" data-bind="with: currentContainer"> 
         <span class="estimatepage_info_text">container number</span> 
         <div data-bind="" class="estimate_info_DIV"> 
          <span data-bind="text: ContainerNumber"></span> 
         </div> 
        </div> 
        <div style="clear: both;"></div> 
        <div class="estimate_info" data-bind="with: currentBillingCustomer"> 
         <span class="estimatepage_info_text">billing customer</span> 
         <div data-bind="click: $parent.showCustomerModal" class="estimate_info_DIV"> 
          <span data-bind="text: Name"></span> 
         </div> 
         <button class="flatButtonSmall" data-bind="click: $parent.showCustomerModal">&#8250;</button> 
        </div> 
        <div style="clear: both;"></div> 
        <div class="estimate_info" data-bind='with: currentContainer'> 
         <span class="estimatepage_info_text">equipment</span> 
         <div data-bind="click: $parent.showContainerModal" class="estimate_info_DIV"> 
          <span data-bind="text: ContainerNumber"></span> 
         </div> 
         <button class="flatButtonSmall" data-bind="click: $parent.showContainerModal">&#8250;</button> 
        </div> 
        <div style="clear: both;"></div> 
       </fieldset> 
      </div> 
      <div class="span6"> 
        <fieldset> 
        <!--<legend></legend> Deze niet toevoegen uitlijning is dan niet goed!--> 
        <div class="estimate_info" data-bind="with: currentRepairOrder"> 
         <span class="estimatepage_info_text">repair order</span> 
         <div class="estimate_info_DIV"> 
          <span data-bind="text: RepairOrderID"></span> 
         </div> 
        </div> 
        <div style="clear: both;"></div> 
        <div class="estimate_info" data-bind='with: currentCustomer'> 
         <span class="estimatepage_info_text">relation</span> 
         <div data-bind="click: $parent.showCustomerModal" class="estimate_info_DIV"> 
          <span data-bind="text: Name"></span> 
         </div> 
         <button class="flatButtonSmall" data-bind="click: $parent.showCustomerModal">&#8250;</button> 
        </div> 
        <div style="clear: both;"></div> 
        <div class="estimate_info" data-bind="with: currentRepairOrder"> 
         <span class="estimatepage_info_text">creation date</span> 
         <div class="estimate_info_DIV"> 
          <span data-bind="text: Created().getDate() + '-' + (Created().getMonth() + 1) + '-' + Created().getFullYear()"></span> 
         </div> 
        </div> 
        <div style="clear: both;"></div> 
       </fieldset> 
      </div> 
     </div> 
    </div> 
    <div class="span6"> 
     <!-- Memo's --> 
     <div class="fiftypx"> 
      <span class="main_title">MEMO'S</span> 
      <button class="newButton" data-bind="click: addMemo">NEW</button> 

      <button data-bind="click: doneEstimating" style="width: 130px;float: right;margin-right: 25px;" class="flatButtonBig" data-bind="">DONE</button> 
      <div style="clear: both;"></div> 
      <div> 
       <div class="loader" data-bind="css: { active: isLoading }"> 
        <i class="icon-spinner icon-2x icon-spin"></i> 
       </div> 
      </div> 

     </div> 
     <div id="memosTable"> 
      <table class="table" style="margin-left: -25px;"> 
       <thead> 
        <tr> 
         <th></th><th>date/user</th><th>memo</th><th></th> 
        </tr> 
       </thead> 
       <tbody data-bind="visible: memos().length > 0, foreach: memos"> 
        <tr class="rowStyleFront"> 
         <td style="width:25px;"></td> 
         <td style="width: 115px;"> 
          <!-- date and user --> 
          <!-- text: MemoEntity._latestValue.CreationDate --> 
          <span class="upperSpan" data-bind="">Datum</span> 
          <div style="clear: both;"></div> 
          <span class="lowerSpan" data-bind="text: MemoEntity._latestValue.Employee().Username()"></span> 
         </td> 
         <td style="width: 300px;"> 
          <!-- memo --> 
          <span style="display: inline; background-color: #f4931D; color: #FFFFFF; padding-right: 7px; padding-left: 5px;" class="upperSpan" data-bind="textToUpperCase: MemoEntity._latestValue.Type"></span> 
          <div style="clear: both;"></div> 
          <span style="margin-top: 20px; width: inherit;" class="lowerSpan" data-bind="text: MemoEntity._latestValue.Description"></span> 
         </td> 
         <td style="width: 50px;"><button data-bind="click: $parent.selectedMemo" style="float: right;" class="flatButtonBig" data-bind="">X</button></td> 
        </tr>    
       </tbody> 
       <tbody data-bind="visible: memos().length == 0"> 
        <tr class="rowStyleFront"> 
         <td style="width:25px;"></td> 
         <td colspan="3">You haven't made any memo's yet.</td> 
        </tr>    
       </tbody> 
      </table> 
     </div> 
    </div> 
</div> 

<div class="row-fluid"> 
    <div class="span6"> 
     <!-- Add new repairline button and text --> 
     <div class="fiftypx"> 
      <span class="main_title">REPAIRLINES</span> 
      <button class="newButton" data-bind="click: addRepairline">NEW</button> 
     </div> 
    </div> 
    <div class="span6" style="line-height: 50px;"> 
     <!-- totals! --> 
     <div class="row-fluid"> 
      <div class="span4">Hours cost: <span style="font-size: 16px;" data-bind="text: hourscost()"></span></div> 
      <div class="span4">Materials: <span style="font-size: 16px;" data-bind="text: materialcost()"></span></div> 
      <div class="span4">Total: <span style="font-size: 16px;" data-bind="text: grandtotal()"></span></div> 
     </div> 
    </div> 
</div> 

<div class="row-fluid"> 
    <div class="span12"> 
     <!-- Table with all repairlines --> 
     <table class="table" style="margin-left: -25px;"> 
      <thead> 
       <tr> 
        <th></th> 
        <th>Description</th> 
        <th></th> 
        <th>Code</th> 
        <th>Mat</th> 
        <th>LOC</th> 
        <th>Rep</th> 
        <th>DAM</th> 
        <th>Customer</th> 
        <th>IsAgreement</th> 
        <th>Qty</th> 
        <th>Hours</th> 
        <th>Tariff</th> 
        <th>Costs</th> 
        <th>Lessee</th> 
        <th>Authorized</th> 
        <th>DoRepair</th> 
        <th><!-- Button --></th> <!-- 17 rijen --> 
       </tr> 
      </thead> 
      <tbody data-bind="visible: repairorderlines().length > 0, foreach: repairorderlines"> 
       <tr class="rowStyleFront"> 
        <td style="width:25px;"></td> 
        <td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.Description"></td> 
        <td></td> 
        <td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.InternalCode"></td> 
        <td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.MaterialCode"></td> 
        <td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.LocationCode"></td> 
        <td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.RepairCode"></td> 
        <td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.DamageCode"></td> 
        <td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.Customer().Name()"></td> 
        <td><input type="checkbox" data-bind="checked: RepairOrderLineEntity._latestValue.IsAgreement"/></td> 
        <td data-bind="click: $parent.selectedRepairOrderLine, numericText: RepairOrderLineEntity._latestValue.Quantity"></td> 
        <td data-bind="click: $parent.selectedRepairOrderLine, numericText: RepairOrderLineEntity._latestValue.Hours"></td> 
        <td data-bind="click: $parent.selectedRepairOrderLine, numericText: RepairOrderLineEntity._latestValue.Tariff"></td> 
        <td data-bind="click: $parent.selectedRepairOrderLine, numericText: RepairOrderLineEntity._latestValue.Costs"></td> 
        <td data-bind="click: $parent.selectedRepairOrderLine">-</td> 
        <td><input type="checkbox" data-bind="checked: RepairOrderLineEntity._latestValue.IsAuthorized"/></td> 
        <td><input type="checkbox" data-bind="checked: RepairOrderLineEntity._latestValue.DoRepair"/></td> 
        <td style="width: 50px;"><button class="flatButtonBig" data-bind="click: $parent.selectedRepairOrderLine">&#8250;</button></td> 
       </tr>    
      </tbody> 
      <tbody data-bind="visible: repairorderlines().length == 0"> 
       <tr class="rowStyleFront"> 
        <td style="width:25px;"></td> 
        <td colspan="16">You haven't made any repairlines yet.</td> 
       </tr>    
      </tbody> 
     </table> 
    </div> 
</div> 

Gr。樂華

回答

0

呀,我固定它:)

這裏是我的解釋:每清風功能我已經推遲jQuery的對象,我也有一個全球每頁。在激活函數中,我調用執行所有函數的jQuery的when函數。

define(function (require) { 
    var app = require('durandal/app'), 
     suspendItemSave = false, 
     system = require('durandal/system'), 
     router = require('durandal/plugins/router'), 
     dataservice = require('services/dataservice'), 
     logger = require('services/logger'), 
     allCustomers = ko.observableArray(), 
     allCountries = ko.observableArray(), 
     allVats = ko.observableArray(), 
     allCurrencys = ko.observableArray(), 
     allContainerPropertySettings = ko.observableArray(), 
     entireRepairlineLib = ko.observableArray(), 
     repairAgreementsLib = ko.observableArray(), 
     addVatModal = require('viewmodels/manager/addVat'), 
     vatModal = require('viewmodels/manager/Vat'), 
     addCurrencyModal = require('viewmodels/manager/addCurrency'), 
     currencyModal = require('viewmodels/manager/currency'), 
     addCountryModal = require('viewmodels/manager/addCountry'), 
     countryModal = require('viewmodels/manager/country'), 
     addContainerPropertySettingModal = require('viewmodels/manager/addContainerPropertySetting'), 
     containerPropertySettingModal = require('viewmodels/manager/containerPropertySetting'), 
     repairlineModal = require('viewmodels/manager/predefinedRepairline'), 
     addPredefinedRepairlineModal = require('viewmodels/manager/addPredefinedRepairline'), 
     repairAgreement = require('viewmodels/manager/repairAgreement'), 
     deferred = $.Deferred(); 


    function getEntireRepairLib() { 
     var d = $.Deferred(); 
     breeze.EntityQuery.from("EntireRepairLineLib") 
       .using(dataservice.manager) 
       .execute().then(function (data) { 
        data.results.forEach(function (item) { 
         extendItem(item); 
         entireRepairlineLib.push(new repairlineModal(item)); 
        }); 
        system.log("Succesfully fetched EntireRepairLineLib"); 
        d.resolve(); 
       }).fail(function (data) { 

       }); 
     return d.promise(); 
    } 

    function getRepairAgreements() { 
     var d = $.Deferred(); 
     breeze.EntityQuery.from("RepairAgreements") 
      .using(dataservice.manager) 
      .execute().then(function(data) { 
       data.results.forEach(function(item) { 
        extendItem(item); 
        repairAgreementsLib.push(new repairAgreement(item)); 
       }); 
       system.log("Succesfully fetched RepairAgreement"); 
       d.resolve(); 
      }); 
     return d.promise(); 
    } 

    function init() { 
     dataservice = DataserviceClass.getInstance(); //Get the dataservice instance. 
    } 

    init(); 
    return { 
     router: router, 
     displayName: 'Management page', 
     allCustomers: allCustomers, 
     allCountries: allCountries, 
     allVats: allVats, 
     allCurrencys: allCurrencys, 
     allContainerPropertySettings: allContainerPropertySettings, 
     entireRepairlineLib: entireRepairlineLib, 
     repairAgreementsLib: repairAgreementsLib, 
     activate: function() {  
      $.when(getEntireRepairLib(), getRepairAgreements(), etc, etc, .....) 
       .done(function() { 
        deferred.resolve(); 
        console.log("Done loading"); 
        logger.log("Managementpage started!", null, null, true); 
        system.log("Managementpage started!"); 
       });      
      return deferred.promise(); 
     }, 
     deactivate: function() { 
      allCustomers([]); 
      allCountries([]); 
      allVats([]); 
      allCurrencys([]); 
      allContainerPropertySettings([]); 
      entireRepairlineLib([]); 
      repairAgreementsLib([]); 
      deferred = $.Deferred(); //reset the deferred! 
     } 
    }; 
}); 

如果還有其他(更好的)方法,請讓我現在!我檢查了Chrome的控制檯,並且看到日誌都在綁定之前執行!這是問題!

0

編輯

好吧,我會盡力幫助你儘可能地和沿途點了幾樣東西了 -

  1. 在Visual Studio中打開項目或選擇編輯器並執行「查找」,搜索整個項目,以及在視圖模型或視圖中看到的'latestValue',或除Knockout庫內部任何位置的任何地方,都需要將其刪除。如果你需要從一個KO觀察或ObservableArray的值,可以使用getter函數 -

    if (memos._latestValue.length == 0) 
    

應該

if (memos().length == 0) 

我知道,我已經回答過一個問題要問你,並建議該,我回過頭來仔細檢查它是否正確,但是認真你需要這樣做,你正在使用_latestValue繞過Knockout的核心功能。

  1. 我查了一些你所創建的ID可觀的,它似乎在創建它們,並將它們設置爲-1,但從來沒有使用它們 - 將它們全部刪除。如果您需要的currentContainer或其他的ID只需調用currentContainer()。id()即可。

  2. 當你定義一個observableArray時,你不需要將它設置爲無,也不需要在停用時調用removeAll()。

定義一個變量的第一次 -

memos = ko.observableArray(); 

設置一個變量等於什麼 -

memos = ko.observableArray([]); 

所以,當你停用只是將其設置爲無平等,而不是使用移除所有()。

這似乎很多工作,但實際上並不是這樣,我有一種感覺,我們可能會發現爲什麼您的視圖模型僅在第二次加載過程中加載一半數據。

看這裏!!!

在一些地方,你設置observables等於data.results,這是好的,但讓我們試着清理它們一點(我並不是說在第一個項目中沒有名爲Customer的函數該陣列data.results,但如果沒有這將解決這個問題) -

currentOrder(data.results[0]); 

var customer = data.results[0].Customer(); 
//extendItem(customer); 
currentCustomer(customer); 

var container = data.results[0].Container(); 
//extendItem(container); 
currentContainer(container); 

讓我們調整,爲 -

currentOrder(data.results[0]); 
currentCustomer(currentOrder().Customer()); 
currentContainer(currentOrder().Container()); 

* 你停用功能*

deactivate: function() { 
      memos([]); 
      repairorderlines([]); 
      currentOrder(null); 
      currentRepairOrder(null); 
      currentCustomer(null); 
      currentBillingCustomer(null); 
      currentContainer(null); 
     }, 

原來的答案

消除微風的問題 - 如果你的淘汰賽觀測值都充滿了數據,然後按照預期的查詢可能工作。

消除淘汰賽的問題 - 如果您的視圖模型填充了數據,那是一個好兆頭。如果視圖本身存在綁定問題,可以嘗試幾件事 -

  1. 查看控制檯 - 任何數據綁定都會中斷嗎?
  2. 您的視圖是否處理可以在聲明綁定之後加載數據的情況?

這將等到可觀察到的陣列試圖顯示數據之前加載 -

<ul data-bind="foreach: myArray"><li data-bind="text: name"></li></ul> 

這不會 -

<h1 data-bind="text: name" /> 

但是你可以調試或防止從綁定打破像這樣 -

<h1 data-bind="text: $data.name" /> 

Ë作爲問題的限制Durandal -

Durandal的框架非常穩定,並且非常懷疑您發現了一個其他人沒有發現的錯誤。更有可能是第一次訪問該網頁時,您正在做的事情與第二次訪問該網頁時不同。沒有代碼,我們不能幫助進一步調試它。

關於Durandal的一個注意事項 - 如果你的視圖模型是一個Singleton對象,並且你依賴於某些數據到總是在那裏你應該考慮使用構造模塊。更多信息@http://durandaljs.com/documentation/Creating-A-Module/

+0

我已經添加了一些代碼一個完整的頁面與viewmodel和觀點希望它有幫助。我還添加了一些更多的文字和解釋。 –

+0

好吧我給答案增加了很多,我希望它能幫助你找到問題。 –

+0

我遵循了你的所有建議,但他們中沒有人做過這個工作:(其他想法? –

0

視圖模型:

define(function (require) { 
    var router = require('durandal/plugins/router'), 
     app = require('durandal/app'), 
     system = require('durandal/system'), 
     addmemo = require('viewmodels/modals/addMemo'), 
     container = require('viewmodels/modals/container'), 
     memo = require('viewmodels/modals/memo'), //probably in the models folder but for now its okay 
     dataservice = require('services/dataservice'), 
     logger = require('services/logger'), 
     addRepairOrderLine = require('viewmodels/modals/addRepairOrderLine'), 
     repairorderline = require('viewmodels/modals/RepairOrderLine'), 
     customerModal = require('viewmodels/modals/customer'), 
     currentLoggedInEmployee = ko.observable(), 
     memos = ko.observableArray(), 
     deferred = $.Deferred(), 
     repairorderlines = ko.observableArray(), 
     tasksToMonitor = [], 
     isLoading = ko.observable(false), 
     suspendItemSave = false, 
     rightParameters = true, 
     notDone = true, 
     hourscost = ko.observable(0.0), 
     materialcost = ko.observable(0.0), 
     grandtotal = ko.observable(0.0), 
     currentRepairOrderID = -1, 
     currentOrderID = -1, 
     currentOrder = ko.observable(), 
     currentRepairOrder = ko.observable(null), 
     currentContainerID = -1, 
     currentCustomer = ko.observable(null), 
     currentBillingCustomer = ko.observable(null), 
     currentContainer = ko.observable(null), 
     showElementFade = function(elem) { if (elem.nodeType === 1) $(elem).hide().slideDown(); }, 
     hideElementFade = function(elem) { if (elem.nodeType === 1) $(elem).slideUp(function() { $(elem).remove(); }); }; 

    function extendItem(itemToExtend) { 
     if (itemToExtend.isEditing) return; // already extended 

     itemToExtend.isEditing = ko.observable(false); 
     //Deze functie wordt getriggerd zodra het aanpassen klaar is! 

     // listen for changes with Breeze PropertyChanged event 
     itemToExtend.entityAspect.propertyChanged.subscribe(function() { 
      if (itemToExtend.propertyChangedPending || suspendItemSave) { return; } 
      // throttle property changed response 
      // allow time for other property changes (if any) to come through 
      itemToExtend.propertyChangedPending = true; 
      setTimeout(validateAndSaveModifiedItem, 10); 

      function validateAndSaveModifiedItem() { 
       if (itemToExtend.entityAspect.entityState.isModified()) { 
        if (itemToExtend.entityAspect.validateEntity()) { 
         dataservice.saveChanges(); 
        } else { // errors 
         itemToExtend.isEditing(true); // go back to editing 
        } 
        //also update finance! 
        updateFinance(); 
       } 
       itemToExtend.propertyChangedPending = false; 
      } 
     }); 
    } 

    function updateFinance() { 
     materialcost(0.0); 
     hourscost(0.0); 
     grandtotal(0.0); 

     ko.utils.arrayForEach(repairorderlines(), function (line) { 
      if (line.RepairOrderLineEntity().DoRepair()) { 
       var materialcostTemp = (line.RepairOrderLineEntity().Costs() * line.RepairOrderLineEntity().Quantity()) + materialcost(); 
       materialcost(materialcostTemp); 

       var hourscostTemp = (line.RepairOrderLineEntity().Tariff() * line.RepairOrderLineEntity().Hours()) + hourscost(); 
       hourscost(hourscostTemp); 
      } 
     }); 
     // materialcost = ko.observable(materialcost); 
     // hourscost = ko.observable(hourscost); 
     grandtotal(materialcost() + hourscost()); 

     //Showing the rounded numbers with the euro sign 
     hourscost("€ " + parseFloat(Math.round(hourscost() * 100)/100).toFixed(2)); 
     materialcost("€ " + parseFloat(Math.round(materialcost() * 100)/100).toFixed(2)); 
     grandtotal("€ " + parseFloat(Math.round(grandtotal() * 100)/100).toFixed(2)); 
    } 
    //This function checks each task in the tasktomonitor array when they are all false (so loading is done) 
    //The global iSloading is set to false, because loading is done:) 
    function checkTasks() { 
     var loadingDone = true; 
     tasksToMonitor.forEach(function (item) { 
      if (item[1] == false) 
       loadingDone = false; 
     }); 
     if (loadingDone) { 
      deferred.resolve(); 
      isLoading(false); 
     } 
    } 

    //This function is called ones, only when the page hasn't loaded yet! 
    function init() { 
     dataservice = DataserviceClass.getInstance(); 

     dataservice.getSpecificID('Employees', 'EmployeeID', 1).then(function (data) { 
      currentLoggedInEmployee = data.results[0]; 
     }).fail(function(data) { 
      logger.logError('Error fetching the current logged in employee!', null, null, true); 
     }); 
    } 
    init(); 

    return { 
     displayName: 'Estimating page', 
     router: router, 
     currentCustomer: currentCustomer, 
     currentContainer: currentContainer, 
     currentRepairOrder: currentRepairOrder, 
     currentBillingCustomer: currentBillingCustomer, 
     memos: memos, 
     repairorderlines: repairorderlines, 
     isLoading: isLoading, 
     hourscost: hourscost, 
     materialcost: materialcost, 
     grandtotal: grandtotal, 
     activate: function (Context) { 
      currentRepairOrder(null); 
      currentBillingCustomer(null); 
      rightParameters = true; 
      //also need to check if ids exist in DB!! 
      if (!Context.hasOwnProperty("orderid") || isNaN(Context.orderid) || 
       !Context.hasOwnProperty("repairorderid") || isNaN(Context.repairorderid)) { 
       rightParameters = false; 
       system.log('Not all the right parameters!'); 
       router.navigateTo('#/error'); //eventueel parameters meegeven! 
       return; 
      } 

      //set id's 
      currentRepairOrderID = Context.repairorderid; 
      currentOrderID = Context.orderid; 
      tasksToMonitor = []; //empty the task function 

      //fetching all necessary information 
      //estimatepage/:orderid/:repairorderid 
      //Fetch: 
      /* 
       billing customer 
       owner container 
       container number 
       container propertys 
       repair order 
       creation date of repairorder 
       fetching memo's with repairorder 
       fetching repairorderlines 
      */ 

      //In this order the container fetch right away, thats one call less to the server 
      breeze.EntityQuery.from("Orders") 
       .where("OrderID", "==", parseInt(Context.orderid)) 
       .expand("Customer, Customer.PostCountry, Customer.VisitCountry, Container, Container.ContainerManufacturer, Container.ContainerType, Container.Owner") 
       .using(dataservice.manager) 
       .execute().then(function (data) { 
        if (data.results.length < 1) { 
         system.log('Not all the right parameters!'); 
         rightParameters = false; 
         router.navigateTo('#/error'); //eventueel parameters meegeven! 
         return; 
        } 
        currentOrder(data.results[0]); 
        currentCustomer(currentOrder().Customer()); 
        currentContainer(currentOrder().Container()); 
       }).fail(function (data) { 
        logger.logError('Error fetching the current Order!', null, null, true); 
       }).fin(function() { 

       }); 
      //In the future this will be calling the order 2 

      tasksToMonitor.push(new Array('fetch_repairorders', false)); 
      breeze.EntityQuery.from("RepairOrders") 
       .where("RepairOrderID", "==", parseInt(Context.repairorderid)) 
       .expand("BillingCustomer, BillingCustomer.PostCountry, BillingCustomer.VisitCountry") 
       .using(dataservice.manager) 
       .execute().then(function (data) { 
        currentRepairOrder(data.results[0]); 
        currentBillingCustomer(data.results[0].BillingCustomer()); 
       }).fail(function (data) { 
        logger.logError('Error fetching current repairorder!', null, null, true); 
       }).fin(function() { 
        //first set the value to true (loading done) 
        //Call the global function to check each process 
        tasksToMonitor[0][1] = true; 
        checkTasks(); 
       }); 

      //by adding this if statements the data is only loaded if it hasn't been loaded yet! 
      //voor nu alle memos van alle medewerkers, later alleen die van betreffende? 
      tasksToMonitor.push(new Array('fetch_memos', false)); 
      if (memos().length == 0) { 
       breeze.EntityQuery.from("Memos") 
        .where("RepairOrderID", "==", parseInt(Context.repairorderid)) 
        //.expand("Customer, Container, Container.ContainerManufacturer, Container.ContainerType") 
        .expand("Employee") 
        .using(dataservice.manager) 
        .execute().then(function (data) { 
         data.results.forEach(function (item) { 
          extendItem(item); 
          memos.push(new memo(item)); 
         }); 
         system.log("Initialization succesfull!"); 
         logger.logSuccess('Initialization succesfull', null, 'estimatepage', true); 
        }).fail(function (data) { 
         logger.logError('Error fetching memos!', null, null, true); 
        }).fin(function() { 
         tasksToMonitor[1][1] = true; 
         checkTasks(); 
        }); 
      } 

      tasksToMonitor.push(new Array('fetch_repairorderlines', false)); 
      if (repairorderlines().length == 0) { 
       breeze.EntityQuery.from("RepairOrderLines") 
        .where("RepairOrderID", "==", parseInt(Context.repairorderid)) 
        .expand("Customer") 
        .using(dataservice.manager) 
        .execute().then(function (data) { 
         data.results.forEach(function (item) { 
          extendItem(item); 
          repairorderlines.push(new repairorderline(item)); 
         }); 
         updateFinance(); 
         // 
        }).fail(function (data) { 
         logger.logError('Error fetching repairorderlines!', null, null, true); 
        }).fin(function() { 
         tasksToMonitor[2][1] = true; 
         checkTasks(); 
         // deferred.resolve(); 
        }); 
      } 

      logger.log("Estimating page started!", null, "estimagepage", true); 
      return deferred.promise(); 
      //return; 
     }, 
     canDeactivate: function() { 
      if (rightParameters && notDone) { 
       return app.showMessage('Are you sure you want to leave this page and stop estimating?', 'Navigate', ['Yes', 'No']); 
      } else { 
       return true; 
      } 
     }, 
     deactivate: function() { 
      //remove everything here! I mean remove the data in the models! Everything is already saved ;) 
      memos.removeAll(); 
      repairorderlines.removeAll(); 

      currentRepairOrderID = -1; 
      currentOrderID = -1; 
      currentOrder(null); 
      currentRepairOrder(null); 
      currentContainerID = -1; 
      currentCustomer(null); 
      currentBillingCustomer(null); 
      currentContainer(null); 
     }, 
     showCustomerModal: function(selectedCustomer,element) { 
      app.showModal(new customerModal(selectedCustomer)).then(function() { 

      }).fail(function() { 

      }); 
     }, 
     showContainerModal: function() { 
      app.showModal(new container(currentContainer, currentOrder())).then(function (result) { 

      }).fail(function(result) { 

      }); 
     }, 
     cancelEstimation: function() { 
      app.showMessage('Do you want to delete this estimation?', 'Delete estimate', ['Yes', 'No']).then(function (resultMessageBox) { 
       if (resultMessageBox == "Yes") { 
        //memos.remove(selectedMemo); 
        //selectedMemo.MemoEntity().entityAspect.setDeleted(); 
        // dataservice.saveChanges(); 
       } 
       //else if no the user just clicked OK and everything is saved 
      }); 
     }, 
     addRepairline: function() { 
      //logger.log('Clicked a button yeeeh', null, 'estimatepage', true); 

      //Dit doen: addreapirline de repairline laten maken en de foto's 
      //dan de gemaakte repairline teruggeven aan deze functie. 
      var t = currentRepairOrder().ID(); 
      app.showModal(new addRepairOrderLine(currentRepairOrderID, currentCustomer,currentBillingCustomer)).then(function (result) { 
       if (result != undefined) { 
        extendItem(result); 
        repairorderlines.push(new repairorderline(result)); 
        updateFinance(); 
       } 
      }).fail(function(result) { 
       logger.logError('Error fetching result adding repairline', null, null, true); 
      }); 
     }, 
     addMemo: function() { 
      app.showModal(new addmemo(currentLoggedInEmployee)).then(function (result) { 
       if (result != undefined) {     
        var memoN = dataservice.createT({ 
         Description: result[0].Description, 
         EmployeeID: result[0].EmployeeID, //Dit moet echt de employee zelf zijn niet zijn ID!!! 
         Type: result[0].Type, 
         RepairOrderID: currentRepairOrderID 
        }, 'tblMemo'); 

        if (memoN.entityAspect.validateEntity()) { 
         extendItem(memoN); 
         memos.push(new memo(memoN)); 
         dataservice.saveChanges(); 
         logger.logSuccess('Memo added succesfully!', null, null, true); 
        } 
       } 
      }).fail(function(result) { 
       logger.logError('Something went wrong adding a memo!', null, 'estimatepage', true); 
      }); 
     }, 
     selectedRepairOrderLine: function (selectedRepairOrderLine, element) { 
      app.showModal(selectedRepairOrderLine).then(function (result) { 
       if (result) { 
        app.showMessage('Do you want to delete this RepairOrderLine?', 'Delete RepairOrderLine', ['Yes', 'No']).then(function (resultMessageBox) { 
         if (resultMessageBox == "Yes") { 
          repairorderlines.remove(selectedRepairOrderLine); 
          selectedRepairOrderLine.RepairOrderLineEntity().entityAspect.setDeleted(); 
          dataservice.saveChanges(); 
          updateFinance(); //dont remove this one its called ! 
          logger.logSuccess('Repairline deleted successfully', null, null, true); 
         } 
         //else if, no the user just clicked OK and everything is saved so also updatefinance is called a couple of line further 
        }); 
       } 
       updateFinance(); //But we must update the finance because things could have been changed! 
      }).fail(function() { 
       logger.logError('Something went wrong selecting the memo!', null, 'estimatepage', true); 
      }); 
     }, 
     selectedMemo: function (selectedMemo, element) { 
       app.showMessage('Do you want to delete this memo?', 'Delete memo', ['Yes', 'No']).then(function (resultMessageBox) { 
        if (resultMessageBox == "Yes") { 
         memos.remove(selectedMemo); 
         selectedMemo.MemoEntity().entityAspect.setDeleted(); 
         dataservice.saveChanges(); 
        } 
        //else if no the user just clicked OK and everything is saved 
      }).fail(function() { 
       logger.logError('Something went wrong selecting the memo!', null, 'estimatepage', true); 
      }); 
     }, 
     /* 
     selectedMemo: function (selectedMemo, element) { 
      app.showModal(selectedMemo).then(function (result) { 
       if (result) { 
        app.showMessage('Do you want to delete this memo?', 'Delete memo', ['Yes', 'No']).then(function (resultMessageBox) { 
         if (resultMessageBox == "Yes") { 
          memos.remove(selectedMemo); 
          selectedMemo.MemoEntity().entityAspect.setDeleted(); 
          dataservice.saveChanges(); 
         } 
         //else if no the user just clicked OK and everything is saved 
        }); 
       } 
      }).fail(function() { 
       logger.logError('Something went wrong selecting the memo!', null, 'estimatepage', true); 
      });   
     }, 
     */ 
     /* 
     getUser: function (userId) { 
      var t; 
      dataservice.getSpecificID('AllEmployees', 'EmployeeID', userId).then(function (data) { 
       t = "Dit is mijn tekst: " + data.results[0].Username(); 
       return t; 
      }); 
      return t; 
     },*/ 
     removeMemos: function() { 
      var memoSelectedToBeRemoved = false; 

      $.each(memos(), function (i, l) { 
       if (l.markedForDeletion()) { 
        memoSelectedToBeRemoved = true; 
       } 
      }); 

      if (memoSelectedToBeRemoved == false) { 
       app.showMessage('No memos selected!','No memos'); 
       return; //No memos selected to be deleted! 
      } 

      app.showMessage('Do you want to delete the selected memos?', 'Delete memos', ['Yes', 'No']).then(function(resultMessageBox) { 
       if (resultMessageBox == "Yes") { 
        //create a temp new KOarray 
        //for each memo that is not to be deleted put them in a new list 
        //At the end remove all memos from memos. then push all memos from the temp list to memos. 
        var newMemoList = ko.observableArray([]); 
        var numberOfMemos = memos().length; 
        $.each(memos(), function (i, l) { 
         if (!l.markedForDeletion()) { 
          newMemoList.push(l); 
         } else { 
          l.MemoEntity().entityAspect.setDeleted(); 
         } 
        }); 
        dataservice.saveChanges(); 
        memos.removeAll(); 

        $.each(newMemoList(), function (i, l) { 
         memos.push(l); 
        }); 
        logger.logSuccess('A total of: ' + (numberOfMemos - newMemoList().length) + ' memos have been removed.', null, null, true); 
       } 
      }); 
     }, 
     doneEstimating: function() { 
      if (repairorderlines().length < 1) { 
       app.showMessage('No repairlines added yet!', 'Estimate cannot be ready'); 
       return; 
      } 

      app.showMessage('Are you sure you are done estimating?', 'Estimate done', ['Yes', 'No']).then(function (resultMessageBox) { 
       if (resultMessageBox == "Yes") { 
        //sent repairOrderID to server 
        //server fetch all data like repairorderlines etc. 
        //server sents mail to user 
        notDone = false; 
        router.navigateTo('startingpage'); 
       } 
      }); 
     } 
    }; 
}); 
+0

當我在Chrome或IE等瀏覽器中查看我的控制檯時,我看到的值是:S –

0

我發現的文件:在DurandalJS框架viewModelBinder.js一部分需要綁定的照顧。

define(['./system'], function (system) { 
    var viewModelBinder; 
    var insufficientInfoMessage = 'Insufficient Information to Bind'; 
    var unexpectedViewMessage = 'Unexpected View Type'; 

    function doBind(obj, view, action) { 
     if (!view || !obj) { 
      if (viewModelBinder.throwOnErrors) { 
       throw new Error(insufficientInfoMessage); 
      } else { 
       system.log(insufficientInfoMessage, view, obj); 
      } 
      return; 
     } 

     if (!view.getAttribute) { 
      if (viewModelBinder.throwOnErrors) { 
       throw new Error(unexpectedViewMessage); 
      } else { 
       system.log(unexpectedViewMessage, view, obj); 
      } 
      return; 
     } 

     var viewName = view.getAttribute('data-view'); 

     try { 
      system.log('Binding', viewName, obj); 

      viewModelBinder.beforeBind(obj, view); 
      action(); 
      viewModelBinder.afterBind(obj, view); 
     } catch (e) { 
      if (viewModelBinder.throwOnErrors) { 
       throw new Error(e.message + ';\nView: ' + viewName + ";\nModuleId: " + system.getModuleId(obj)); 
      } else { 
       system.log(e.message, viewName, obj); 
      } 
     } 
    } 

    return viewModelBinder = { 
     beforeBind: system.noop, 
     afterBind:system.noop, 
     bindContext: function(bindingContext, view, obj) { 
      if (obj) { 
       bindingContext = bindingContext.createChildContext(obj); 
      } 

      doBind(bindingContext, view, function() { 
       if (obj && obj.beforeBind) { 
        obj.beforeBind(view); 
       } 

       ko.applyBindings(bindingContext, view); 

       if (obj && obj.afterBind) { 
        obj.afterBind(view); 
       } 
      }); 
     }, 
     bind: function(obj, view) { 
      doBind(obj, view, function() { 
       if (obj.beforeBind) { 
        obj.beforeBind(view); 
       } 

       ko.applyBindings(obj, view); 

       console.log(obj); 

       if (obj.afterBind) { 
        obj.afterBind(view); 
       } 
      }); 
     } 
    }; 
}); 

當我調試我看到綁定的值。然後我看到一些價值確實有時是空的。所以當它們被捆綁時它們是空的。但是當我輸入一個全新的價值時,它們不會重新綁定。

我該如何解決這個問題?當所有的異步調用都已準備就緒並且neccassery屬性被填充時,該頁面僅被綁定?

相關問題