0

Hi folks im having a bit of difficulty wraping my head around using require js and knockout js together. I`m trying to implement require js onto an existing project I had going. Everything was going well until I hit a road block with knockout.

I was trying to follow the example provided on the knockout page here: http://knockoutjs.com/documentation/amd-loading.html

When trying ko.applyBindings(new GDI_Application()); it just comes back as undefined. Ive also setup https://github.com/rniemeyer/knockout-amd-helpers to load external templates. Followed another guide here http://www.newsuntold.dk/post/using-requirejs-and-knockout-amd-helpers-with-knockout but still dosent make any difference still getting Uncaught TypeError: undefined is not a function

What do you guys think im missing?

UPDATED CODE: My HTML code:

<script data-main="js/GDI_MAIN" src="js/require.js"></script>

Here is my GDI_MAIN js code:

require.config({
    paths: {
        "jqueryUI": "../assets/jqueryUI/jquery-ui.min",
        "bootstrap": "bootstrap.min",
        "bootstrap_select": "../assets/silviomoreto-bootstrap-select-a8ed49e/dist/js/bootstrap-select.min",
        "jquery_timepicker": "jquery-ui-timepicker-addon",
        "jqueryui_timepicker_ext":  "jquery-ui-sliderAccess",
        "moment": "moment",
        "cookie": "js.cookie",
        "knockout-amd-helpers": "knockout-amd-helpers.min",
        "text": "text"
    },
        "shim": {
        bootstrap: {
            deps : [ 'jquery'],
            exports: 'Bootstrap'
        },
        bootstrap_select: {
            deps : [ 'jquery', 'bootstrap'],
            exports: 'Bootstrap_Select'
        },      
        jquery_timepicker: {
            deps : [ 'jquery'],
            exports: 'Jquery_Timepicker'
        },
        jqueryui_timepicker_ext: {
            deps : [ 'jquery'],
            exports: 'Jqueryui_Timepicker_Ext'
        }   
    }
});

require(["knockout", "GDI_Application", "GDI_Buttons", "GDI_common", "knockout-amd-helpers", "text", "moment"], function (ko, GDI_Application) {
ko.amdTemplateEngine.defaultPath = "../templates";
ko.applyBindings(new GDI_Application());
GDI_Application.fetchdata();


});

This is the GDI_Application code:

define(["knockout", "jquery", "jqueryUI", "bootstrap", "bootstrap_select","jquery_timepicker", "jqueryui_timepicker_ext", "moment"], function(ko, $) {
ko.bindingHandlers.modal = {
    init: function (element, valueAccessor) {
        $(element).modal({
            show: false
        });

        var value = valueAccessor();
        if (typeof value === 'function') {
            $(element).on('hide.bs.modal', function() {
               value(false);
            });
        }
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
           $(element).modal("destroy");
        });

    },
    update: function (element, valueAccessor) {
        var value = valueAccessor();
        if (ko.utils.unwrapObservable(value)) {
            $(element).modal('show');
        } else {
            $(element).modal('hide');
        }
    }
}

incidentViewModel = function IncidentViewModel() {
    var self = this;
    self.showDialog = ko.observable(false);
    self.incidents = ko.observableArray();
    self.currentIncident = ko.observable();

    Incident.BASE_URL = '../../_vti_bin/listData.svc/GDI_DEV_Incidents';
    Incident.CREATE_HEADERS = {"accept": "application/json;odata=verbose"};
    Incident.UPDATE_HEADERS = {"accept": "application/json;odata=verbose","If-Match": "*"};

    self.fetchdata = function() {
    console.log("fetching - Attempting to execute code.");
    $.getJSON(Incident.BASE_URL+filterlist+orderlist,
        function(data) {        
            if (data.d.results) {       
                self.incidents(data.d.results.map(function(item) {
                return new Incident(item);
                }));
                $('#loading').hide("slow");
                $('#IncidentTable').show("slow");
                console.log("fetching data completed");
            }else {
                console.log("no results received from server");
                }
        });
    }

    self.saveorupdate = function() {
    console.log("save function executed");
        var id = this.ID,
            url = Incident.BASE_URL + (id ? '(' + encodeURIComponent(id) + ')' : '');
            console.log(url);
        return $.ajax(url, {
            type: id ? "MERGE" : "POST",
            data: ko.toJSON({
                Description: this.Description,
                Incident: this.Incident
            }),
            processData: false,
            contentType: "application/json;odata=verbose",
            headers: id ? Incident.UPDATE_HEADERS : Incident.CREATE_HEADERS,
            success: function (data) {
                        incidentViewModel.fetchdata();
                        console.log("Record was sucessfully saved.");

                        }   
        });
    }

    self.ShowSelectedIncident = function(data) {
        self.currentIncident(data);
        self.showDialog(true);
        console.log("The show selected incident has been ran.");    
    }   

    self.clearCurrentIncident = function() {
        self.showDialog(false);
        self.currentIncident(null);
    }

    self.AddNewIncident = function() {
        self.showDialog(true);
        self.currentIncident({ID:"",Description:"",Incident:""});
        console.log("AddNewIncident has been executed sucessfully.");
    }   
}

function Incident(data) {
    var self = this;
    self.ID = data.ID;
    self.Description = ko.observable(data.Description);
    self.Composante = ko.observable(data.Composante);
    self.Incident = ko.observable(data.Incident);
    self.ÉtatValue = ko.observable(data.ÉtatValue);
    self.PrioritéValue = ko.observable(data.PrioritéValue);
    self.Duré = ko.observable(data.Duré);
    self.Service = ko.observable(data.Service);
    self.Début_imputabilité = ko.observable(data.Début_imputabilité);
    self.Début_de_interruption = ko.observable(data.Début_de_interruption);
    self.Fin_de_interruption = ko.observable(data.Fin_de_interruption);
    self.Groupe_Support_Prime = ko.observable(data.Groupe_Support_Prime);
    self.ResponsableValue = ko.observable(data.ResponsableValue);
    self.Impact = ko.observable(data.Impact);
    self.Dépanage = ko.observable(data.Dépanage);
    self.Suivi = ko.observable(data.Suivi);
    self.Ressources = ko.observable(data.Ressources); 
}

return incidentViewModel;
});
4

2 回答 2

1

Off the top of my head: GDI_Application doesn't currently return anything.

It looks like IncidentViewModel is your applications ViewModel so you'll need to return IncidentViewModel from your GDI_Application code so that KO has something to apply the bindings to.

var incidentViewModel = function IncidentViewModel() {
   // your code here;
}

//later on
return incidentViewModel;

As you point out the call to GDI_Application.fetchdata() won't work. This must be some hangover from when you were using quite a different approach.

You could do

 var app = new GDI_Application();
 ko.applyBindings(app);
 app.fetchdata();

Also I'd think about renaming GDI_Application to IncidentViewModel, cause that's what it is really.

于 2016-01-04T08:32:02.903 回答
0

Not a direc answer to the question I know, but I've developed a template for the .NET ecosystem that combines RequireJS with KnockoutJS using a component architecture, and also has NancyFX baked into it for .NET MVC like operation and views as well as including Bootstrap and jQuery support too.

You Can download it from my git hub account at:

https://github.com/shawty/dotnetnotts15

It uses Knockout Components and custom tags, allowing modular code reuse, and even though it's wired for NancyFX, it's just a standard ASP.NET web application, so you could quite easily remove Nancy and add ASP.NET MVC back in or even use any back end of your choosing.

于 2016-03-21T09:24:07.257 回答