4

Ich versuche im Ernst, die angenommene Antwort für this zu folgen. Ich verwende Knockout, Typescript, MVC, VS2017 und Knotenmodule für die meisten meiner Pakete. Das Problem, das ich habe, ist, dass die Bindung nicht aufgerufen wird, aber keine Build-Fehler haben.Der Rest der Eule: Knockout BindingHandlers mit Typescript?

bieten eine Definitionsdatei (sagen myBindings.d.ts)

den folgenden Code

interface KnockoutBindingHandlers { 
     csharpTypes: KnockoutBindingHandler; 
    } 

Referenz diese Definitionsdatei in Ihrem extensions.ts


Datei hinzufügen

So habe ich eine customKoBindings.d.ts so erstellt.

/// <reference path="../../node_modules/@types/knockout/index.d.ts" /> 

interface KnockoutBindingHandlers { 
    dataTablesForEach: KnockoutBindingHandler; 
} 

Ich versuche, die Bindung in meinem cshtml anzuwenden. Muss ich den ko.bindingHandler irgendwie in mein ViewModel einfügen, damit es für die Ansicht verfügbar ist?

<table style="width: 100%" id="copyEmpTrainingSearchResultsTable" class="display" cellspacing="0"> 
               <thead> 
                <tr> 
                 <th data-bind="sort: { arr: employees, prop: 'firstName' }">First Name</th> 
                 <th data-bind="sort: { arr: employees, prop: 'lastName' }">Last Name</th> 
                 <th data-bind="sort: { arr: employees, prop: 'jobTitle' }">Job Title</th> 
                 <th data-bind="sort: { arr: employees, prop: 'primaryManager' }">Manager</th> 
                 <th data-bind="sort: { arr: employees, prop: 'department' }">Department</th> 
                 <th>Trainings</th> 
                </tr> 
               </thead> 
               <tbody data-bind="dataTablesForEach: {data: trainingEmployeeSearchResults, dataTableOptions: {}}"> 
                <tr> 
                 <td data-bind="text: firstName"></td> 
                 <td data-bind="text: lastName"></td> 
                 <td data-bind="text: jobTitle"></td> 
                 <td data-bind="text: primaryManager"></td> 
                 <td data-bind="text: department"></td> 
                 <td><button data-bind="click:$parent.seeTrainings"><i class="fa fa-eye"></i></button></td> 
                </tr> 
               </tbody> 
              </table> 

Die Antwort sagt der Bindung an extensions.ts, hinzuzufügen, so habe ich eine neue Datei. Der verbindliche Code kommt von here. Wie würde ich auf die von mir erstellte Schnittstelle verweisen? Was sollte auf diese Datei zeigen?

extensions.ts

import * as ko from "knockout" 
import * as $ from "jquery"; 

export class KnockoutExtensions { 
    // Constructor 
    constructor() { 
     ko.bindingHandlers.dataTablesForEach = { 
      page: 0, 
      init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
       console.log("init for dataTablesForEach"); 
       var options = ko.unwrap(valueAccessor()); 
       ko.unwrap(options.data); 
       if (options.dataTableOptions.paging) { 
        valueAccessor().data.subscribe(function (changes) { 
         var table = $(element).closest('table').DataTable(); 
         ko.bindingHandlers.dataTablesForEach.page = table.page(); 
         table.destroy(); 
        }, null, 'arrayChange'); 
       } 
       var nodes = Array.prototype.slice.call(element.childNodes, 0); 
       ko.utils.arrayForEach(nodes, function (node: Node) { 
        if (node && node.nodeType !== 1) { 
         node.parentNode.removeChild(node); 
        } 
       }); 
       return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
      }, 
      update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { 
       console.log("update for dataTablesForEach"); 
       var options = ko.unwrap(valueAccessor()), 
        key = 'DataTablesForEach_Initialized'; 
       ko.unwrap(options.data); 
       var table; 
       if (!options.dataTableOptions.paging) { 
        table = $(element).closest('table').DataTable(); 
        table.destroy(); 
       } 
       ko.bindingHandlers.foreach.update(element, valueAccessor, allBindings, viewModel, bindingContext); 
       table = $(element).closest('table').DataTable(options.dataTableOptions); 
       if (options.dataTableOptions.paging) { 
        if (table.page.info().pages - ko.bindingHandlers.dataTablesForEach.page == 0) 
         table.page(--ko.bindingHandlers.dataTablesForEach.page).draw(false); 
        else 
         table.page(ko.bindingHandlers.dataTablesForEach.page).draw(false); 
       } 
       if (!ko.utils.domData.get(element, key) && (options.data || options.length)) 
        ko.utils.domData.set(element, key, true); 
       return { controlsDescendantBindings: true }; 
      } 
     }; 
    } 
} 

Update:

Im DefinitelyTyped documentation's test sie dies nur tun, was ich jetzt im Konstruktor meiner Viewmodel aber init und Update noch versucht haben, werden nicht genannt:

(<any>ko.bindingHandlers).countInits = { init: function() { initCalls++ } }; 

Update 2:

Ich habe nicht requireJS in diesem Projekt verwendet. Wird es benötigt, um den KnockoutBindingHandler zu verknüpfen?


Update 3:

Nach diesen article Überprüfung Ich habe die oben customKoBindings.d.ts mit dem Knotenmodule Referenz in meinem tsconfig.json zu verweisen versucht. Das hat es auch nicht behoben.

{ 
    "compilerOptions": { 
    "outDir": "./wwwroot/build/", 
    "noImplicitAny": false, 
    "noEmitOnError": true, 
    "removeComments": false, 
    "sourceMap": true, 
    "target": "es6", 
    "module": "amd", 
    "moduleResolution": "node" 
    }, 
    "files": [ 
    "./Scripts/Common/customKoBindings.d.ts" 
    ], 
    "exclude": [ 
    "node_modules", 
    "wwwroot" 
    ] 
} 

-Update mehr mitzählen: Es funktioniert!

hat dieses Bild an die Spitze der extensions.ts:

/// <reference path="./customKoBindings.d.ts" /> 

in meinem main.ts diese hinzugefügt:

import { KnockoutExtensions} from "./Common/extensions" 
const koExt = new KnockoutExtensions(); 
+0

Arbeit um für das ultimative Ziel ko und Datentabelle synchron zu halten https://stackoverflow.com/questions/8822590/refresh-knockoutjs-data-in-datatables#31133320 – azulBonnet

Antwort

2

dies von extensions.ts nach oben hinzugefügt:

/// <reference path="./customKoBindings.d.ts" /> 

in meinem main.ts fügte hinzu:

import { KnockoutExtensions} from "./Common/extensions" 
const koExt = new KnockoutExtensions(); 
Verwandte Themen