【问题标题】:Knockout - Total column values in ForEach loop淘汰赛 - ForEach 循环中的总列值
【发布时间】:2013-11-25 11:52:18
【问题描述】:

对 Knockout(和 Durandal/Breeze)非常陌生。 . .

我正在使用 Knockout 的 ForEach 来显示项目中每位员工的几列预测小时数和实际小时数。接下来我想做的是计算每列的预测小时数和实际小时数的差异(hourDiff);我还想对每个员工的名字和姓氏进行格式化。数据来自服务器,我担心我可能已经把自己画到了一个角落里,试图让一切正常工作到这一点。小时数实际上嵌套在每个员工对象中。

[n, n]
 0: n
 1: n
   employee: function dependentObservable() {
  __ko_proto__: function (evaluatorFunctionOrOptions, evaluatorFunctionTarget, options) {
  _latestValue: n
  actualHours: Object[0]
 firstName: function dependentObservable() {
 forecastedHours: Object[0]
 lastName: function dependentObservable() {

我尝试使用 Knockout 的购物车示例,但它与我的设置有点不同,我无法让它正常工作。我也尝试使用 Knockout 的 arrayMap,但没有运气;似乎未评估来自服务器的数据(我使用了此处找到的示例:Computed values in knockout koGrid。我的代码只是为了看看我是否可以通过任何东西。):

function Item(data) {
        system.log('Within Item');
        this.employee = ko.observable(data.employee);

    }

    var mappedData = ko.observableArray(
     ko.utils.arrayMap(staffingResources, function (data) {
         system.log('Within mappedData');
         return new Item(data);
     }
)
);

这是视图模型:

define(['durandal/system', 'durandal/app', 'durandal/activator', 'plugins/router', 'jquery', 'knockout', 'services/projectdetailmanager'],
function (system, app, activator, router, $, ko, pdm) {


    var taskID;
    var laborCategories = ko.observableArray();
    var staffingResources = ko.observableArray();
    var staffingHours = ko.observableArray();


    activate = function (context) {
        pdm.clearManager();
        taskID = context.task
        system.log("taskID = " + context.task);
        staffingHours([]);
        staffingResources.removeAll();
        staffingResources([]);
        getStaffingHours(taskID);
        getLaborCategories();
        getStaffingResources(taskID);

    }
    function getStaffingHours(taskID) {
        return pdm.getStaffingHours(taskID)
               .then(function (data) {
                   staffingHours(data);
               });
    };
    function getStaffingResources(taskID) {
        return pdm.getProjectEmployeesByTask(taskID)
               .then(function (data) {
                   staffingResources(data);
               });
    };

    function getLaborCategories() {
        return pdm.getAllLcats()
               .then(function (data) {
                   laborCategories(data);
               });
    };


    hourDiff = ko.computed(function () {
        return 0;

    });


    function save() {
        pdm.saveChanges();
    };


    return {
        activate: activate,
        staffingResources: staffingResources,
        forecastedHours: forecastedHours,
        actualHours: actualHours,
        laborCategories: laborCategories,
        save: save,
        hourDiff: hourDiff,
        addResource: addResource

    };


});

这里是 html(现在 'hourDiff' 只是用于占位符的常规函数​​):

<table width="100%" border="0">
<thead>
    <tr>
        <td style="font-weight: bold;">Name</td>
        <td style="font-weight: bold;">Labor Category</td>
        <td>&nbsp;</td>
    </tr>
</thead>
<tbody data-bind='foreach: staffingResources'>
    <tr>
        <td style="vertical-align: top;"><span data-bind="text: employee().lastName()" />, <span data-bind="    text: employee().firstName()" /></td>
        <td style="vertical-align: top; width: 20%">
            <select data-bind="options: $root.laborCategories, optionsText: 'name', value: laborCategory, event: { change: $root.save }" /></td>



        <!--Next ForEach Here-->



            <!-- Test -->
            <table border="1">
                <tr>
                    <td>

                        <table border="1">

                            <tr>
                                <td style="font-weight: bold">Month</td>
                            </tr>
                            <tr>
                                <td style="font-weight: bold; width: 20%">Projected: </td>
                            </tr>
                            <tr>
                                <td style="font-weight: bold; width: 20%">Actual: </td>
                            </tr>
                            <tr>
                                <td style="font-weight: bold">Difference: </td>
                            </tr>
                        </table>
                    </td>


                     <!-- ko foreach: $data.employee().hours() -->
                    <td>

                        <table>

                            <tr>
                                <td>Month</td>
                            </tr>
                            <tr>
                                <td>
                                    <input type="text" data-bind="value: forecastedHours, event: { change: $root.save }, valueUpdate: 'afterkeydown'" style="width: 50px;" /></td>
                            </tr>
                            <tr>
                                <td>
                                    <input type="text" data-bind="value: actualHours, event: { change: $root.save }, valueUpdate: 'afterkeydown'" style="width: 50px;" /></td>
                            </tr>
                            <tr>
                                <td><span data-bind="text: $root.hourDiff()" /></td>

                            </tr>


                        </table>


                    </td>
                     <!-- /ko -->
                </tr>

            </table>
            <!-- Test -->

     </tr>
                  </tbody>  
            </table>

任何帮助将不胜感激。为了方便查看,我在这里创建了一个小提琴:http://jsfiddle.net/JfKkm/

【问题讨论】:

    标签: knockout.js breeze durandal


    【解决方案1】:

    我希望你不要对我不利,Jimbo,但感觉你这里一团糟。您的脚本中有大量不相关且无法访问的实用程序。不要误会我的意思,我认为您使用 AMD 很酷,但这只会使您的问题更难回答。

    我建议您简化示例,以便您更好地了解 Knockout 的核心概念,我们可以更好地了解您的问题。我没有在你的脚本中掌握一个有凝聚力的视图模型。 Knockout 基于适合建模的 MVVM 模式。以下伪代码举例说明了我用于定义视图模型的技术。我还包含了一些使用计算属性的示例。

    (function () {
    var vm = {
        laborCategories: ko.observableArray([]),
        staffingResources: ko.observableArray([]),
        staffingHours: ko.observableArray([]),
    }
    
    // init
    var employees = ko.utils.arrayMap(getEmployees(), function(emp) {
        return new Employee(emp); 
    });
    vm.staffingResources(employees);
    
    // private models
    function Employee(data) {
        var model = {
            firstName: ko.observable(data.firstName),
            lastName: ko.observalbe(data.lastName),
            actualHours: ko.observable(data.actualHours),
            forecastedHours: ko.observable(data.forecastedHours),
        }
    
        model.hourDiff = ko.computed(function() {
            return this.actualHours - this.forecastedHours;
        }, model);
        model.nameFormatted = ko.computed(function() {
            return this.lastName() + ', ' + this.firstName();
        }, model);    
    }
    
    ko.applyBindings(model);
    
    // private functions
    function getStaffingHours(taskID) {        
    }
    function getStaffingResources(taskID) {
    }
    function getLaborCategories() {
    }
    function save() {
    }
    })();
    

    我希望这会有所帮助,但如果我完全错过了标记,请原谅我。

    【讨论】:

    • 嘿,文尼!感谢您的回答 - 根本没有对您不利。我想我应该提到我的代码结合了 Durandal 和 Breeze 以及 Knockout。知道这是 Knockout 功能,我为它分配了一个 Knockout 标签。无论如何,您的代码让我对如何完成这项工作有了一些见解。非常感谢。
    • 很高兴我能提供一些价值!如果您在改进模型时需要更多帮助,请更新您的问题并联系我。祝你好运:) --- 顺便说一句,+1(赞成)将不胜感激——如果你认为我的回答值得,那就是。谢谢!
    • 你明白了!加一加。 . .
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    • 2019-03-09
    • 2015-05-28
    • 2017-08-12
    • 2013-06-10
    相关资源
    最近更新 更多