2015-02-05 41 views
0

我已經寫了一個jsfiddle來演示我在下面試圖完成的任務。在父母(遊覽)支付金額輸入中輸入值時有要求,應禁用子(收費)支付金額。反之亦然,當付款金額輸入子(收費)付款金額輸入時,父母禁用。我認爲我已經完美地爲父項工作 - 它禁用了兩個子輸入 - 但是在第二次計費輸入中輸入值時,它不會禁用父項。它也硬了,所以我需要用這部分幫助:KnockoutJS - 禁用綁定 - 如何在父值爲有效時禁用子元素

charges()[0].payAmount() != '' || charges()[0].payAmount() != 0 

我已經看到了這一點 - Knockoutjs Update child when parent's observable changes - 增加一個用戶,但我不認爲我仍然可以訪問/從那裏禁止兒童。或者,也許我可以用jQuery?我也看到了這個 - Is there any way to disable a bunch of form elements at once? - 使用綁定處理程序可能會在孩子的輸入中輸入一個值時處理$ parent的禁用。雖然看起來很複雜。我注意到在ko enable binding documentation中,您可以傳遞一個abitrary表達式,但似乎無法傳入任何參數,例如當前對象。而且,在函數簽名上,如果我添加excursion作爲參數,我已經驗證它是未定義的。這是我曾試圖連接到禁用父結合,無濟於事的功能,如遇到未定義:

function hasChildEntries(encounter) { 
    ko.utils.arrayFirst(encounter.charges(), function (charge) { 
     console.log(charge + ', ' + charge.payAmount() + '...'); 
     if (charge.payAmount() != '' || charge.payAmount() != 0) 
      return true; 
    }); 
    return false; 
}; 

觀點:

<div> 
    <ul class="payments"> 
    <!-- ko foreach: excursions --> 
    <li class="payments"> 
     <div class="payments"> 
     <a href='#' class="expand glyphicon glyphicon-minus-sign" style="color:grey"></a> 
     <a href='#' class="collapse glyphicon glyphicon-plus-sign" style="color:grey"></a> 
     </div> 
     <div class="payments" data-bind="text: 'Excursion ID: ' + id + '&nbsp;&nbsp;Pay Amount: '"></div> 
     <input class="payments" data-bind=" 
      textInput: payAmount, 
      valueUpdate: 'afterkeydown', 
      disable: charges()[0].payAmount() != '' || charges()[0].payAmount() != 0" /> 
     <ul class="payments bullet"> 
     <!-- ko foreach: charges --> 
     <li class="payments"> 
      <div class="payments" data-bind="text: name + '&nbsp;&nbsp;Pay Amount: '"></div> 
      <input class="payments" data-bind=" 
       textInput: payAmount, 
       valueUpdate: 'afterkeydown', 
       disable: $parent.payAmount() != '' || $parent.payAmount() != 0" /> 
     </li> 
     <!-- /ko --> 
     </ul> 
    </li> 
    <!-- /ko --> 
    </ul> 
</div> 

視圖模型/ JavaScript的:

var viewModel = function() { 
    var self = this; 
    self.excursions = ko.observableArray().extend({ rateLimit: 0 }); 

    function Excursion(id, name, chgAmount, payAmount, charges) { 
    this.id = id; 
    this.name = name; 
    this.chgAmount = chgAmount; 
    this.payAmount = ko.observable(''); 
    this.charges = ko.observableArray(charges).extend({ rateLimit: 0 }); 
    }; 

    function Charge(id, name, date, chgAmount, payAmount) { 
    this.id = id; 
    this.name = name; 
    this.date = date; 
    this.chgAmount = chgAmount; 
    this.payAmount = ko.observable(''); 
    }; 

    self.excursions.push(new Excursion('1234', 'Excursion 1', 90.00, 0, undefined)); 
    ko.utils.arrayFirst(self.excursions(), function (excursion) { 
    if (excursion.id = '1234') { 
     excursion.charges.push(new Charge(1, 'Trunk Bay', '02/10/2015', 50.00, 0)); 
     excursion.charges.push(new Charge(2, 'Cinnamon Bay', '02/10/2015', 40.00, 0)); 
    } 
    }); 
    self.excursions.push(new Excursion('1235', 'Excursion 2', 80.00, 0, undefined)); 
    ko.utils.arrayFirst(self.excursions(), function (excursion) { 
    if (excursion.id == '1235') 
     excursion.charges.push(new Charge(3, 'Coral Bay', '02/11/2015', 80.00, 0)); 
    }); 
} 

var vm = new viewModel(); 
ko.applyBindings(vm); 

$(".expand").click(function() { 
    $(this).toggle(); 
    $(this).next().toggle(); 
    $(this).parent().parent().children().last().toggle(); 
}); 
$(".collapse").click(function() { 
    $(this).toggle(); 
    $(this).prev().toggle(); 
    $(this).parent().parent().children().last().toggle(); 
}); 

CSS:

.altRow:nth-child(even) td { background-color: #D8D8D8; } 
ul.payments { list-style:none; float:left; width:100% } 
li.payments { padding-top:10px; float:left; width:100% } 
div.payments { float:left } 
.expand { width:15px;height:15px; } 
.collapse { width:15px;height:15px;display:none } 
ul.payments.bullet {list-style-type: disc;} 
input.payments { width:80px;height:20px; } 

JSFiddle

回答

1

添加一個計算,以您的遊覽模式:

this.hasCharges = ko.computed(function() { 
    for(var i = 0, len = charges().length; i < len; i++) { 
    if(charges()[i].payAmount()) { 
     return true; 
    } 
    } 
    return false; 
}); 

,然後在您的標記,更換

disable: charges()[0].payAmount() != '' || charges()[0].payAmount() != 0" 

disable: hasCharges 

這將禁用父不管它有多少個孩子

編輯:爲您小提琴: http://jsfiddle.net/8j8k7h1c/33/

儘量避免使用「這」在你的職責,範圍界定得到弄糟。我用

var self = this; 

保持觀察到的電荷可由計算函數訪問。

+0

是的,完美。我已經讀過你應該使用計算函數來控制這個,但是沒有意識到你必須將它附加到該函數中,以便該父母/孩子的實例彼此瞭解。精湛 - 非常感謝!在功能上使用自我的好處 - 我已經看到了,但並沒有這樣做。還有點新... ... – sfors 2015-02-05 20:22:12

+0

哦,和更好的使用if(收費()[我] .payAmount()){,而不是檢查!=''或!= 0,所以它正在檢查「真理」的表達。好的改變。 – sfors 2015-02-05 20:30:24

+1

爲真實。如果你沒有初始化你的observable,它也會捕獲null/undefined – dfperry 2015-02-05 20:31:43