Coder Social home page Coder Social logo

rniemeyer / knockout-amd-helpers Goto Github PK

View Code? Open in Web Editor NEW
193.0 16.0 34.0 671 KB

This plugin is designed to be a lightweight and flexible solution to working with AMD modules in Knockout.js.

License: MIT License

JavaScript 96.78% HTML 1.34% CSS 1.88%

knockout-amd-helpers's Introduction

knockout-amd-helpers

What is the point of this library?

This plugin is designed to be a lightweight and flexible solution to working with AMD modules in Knockout.js. It provides two key features:

  1. Augments the default template engine to allow it to load external templates using the AMD loader's text plugin. This lets you create your templates in individual HTML files and pull them in as needed by name (ideally in production the templates are included in your optimized file).

  2. Creates a module binding that provides a flexible way to load data from an AMD module and either bind it against an external template, an anonymous / inline template, or against a template defined within a property on the module itself.

Note: this library was originally designed to work with require.js or curl.js. However, it is possible to use it with webpack. Look at the examples/webpack directory for further details. The app.js file shows how you can override the code used to actually load modules and templates to use with other technologies.

Template Engine

When this plugin is loaded it overrides the default template engine with a version that retains all of the normal functionality, but can also load external templates by using the AMD loader's text plugin.

For example, when doing:

<ul data-bind="template: { name: 'items', foreach: items }"></ul>

The engine will first check to see if there is a script tag with the id of items and if not, it will dynamically require the template using the AMD loader's text plugin. By default, it will use templates/ as the default path and .tmpl.html as the suffix. So, in this case it would require text!templates/items.tmpl.html. Since, the path is built dynamically, if your template lives in a sub-directory, then you could specify your template like: sub/path/items.

These defaults can be overridden by setting properties on ko.amdTemplateEngine. For example:

ko.amdTemplateEngine.defaultPath = "your/path/to/templates";
ko.amdTemplateEngine.defaultSuffix = ".template.html";
ko.amdTemplateEngine.defaultRequireTextPluginName = "text";

Module Binding

This plugin also creates a module binding that provides a number of ways to bind directly against an AMD module. The binding accepts a number of options and tries to make smart choices by default.

Choosing data to bind against

Once the module binding loads an AMD module, there are three scenarios for how it determines the actual data to bind against:

  1. constructor function - If the module returns a function, then it is assumed that it is a constructor function and a new instance is used as the data.

  2. object returned - If the module returns an object directly, then the binding will look for an initializer function (called initialize by default) and:

    a. if there is no initializer or the function does not return a value, then the data will be used directly.

    b. if the initializer function returns a value, then it will be used as the data.

So, this allows the binding to either construct a new instance, use data directly, or call a function that returns data.

Basic example (with inline template):

<div data-bind="module: 'one'">
     <div data-bind="text: name"></div>
</div>

In this example, it will load the module one, determine what data to bind against, and use the inline template.

Basic example (named template - could be external)

<div data-bind="module: 'one'"></div>

In this example, it will load the module one, determine what data to bind against, and use one as the template, which is resolved by the template engine as described above.

Example with options

<div data-bind="module: { name: 'one', data: initialData }"></div>

In this example, it will follow the same logic as the previous example, but it will pass the initialData to the module.

Example with all options

<div data-bind="module: { name: 'one', data: initialData, template: 'oneTmpl',
                          initializer: 'createItem', disposeMethod: 'clean', afterRender: myAfterRender }"></div>

This example includes a number of options options that can be passed to the module binding. In this case, the template is overriden to use oneTmpl, a custom initializer function is used, a custom disposal method is specified, and an afterRender function is passed on to the template binding.

Dynamically binding against a module

The module binding supports binding against an observable or passing an observable for the name, template and data options. The content will be appropriately updated based on the new values. This allows you to dynamically bind an area to a module that is updated as the user interacts with your site.

$module context variable

The module binding adds a $module context variable that can be bound against. This can be useful when you want to bind against the equivalent of $root for just your module. When modules are nested inside other modules, $module will always refer to the root of the current module.

Module Binding - Inline Options

name

Provide the name of the module to load. The module will be loaded by combining the name with the value of ko.bindingHandlers.module.baseDir (defaults to empty). The name will also be used as the template, if the template option is not specified and the element does not have any child elements (inline template).

<div data-bind="module: { name: 'my_module' }"></div>

data

The data option is used to pass values into a constructor function or into the initializer function if the module returns an object directly. If an array is specified, then it will be applied as the arguments to the function (if you really want to pass an array as the first argument, then you would have to wrap it in an array like [myarray]).

<div data-bind="module: { name: 'my_module', data: ['arg1', 'arg2'] }"></div>

template

The template option provides the ability to override the template used for the module. In some cases, you may want to share a template across multiple modules or bind a module against multiple templates.

<div data-bind="module: { name: 'my_module', template: 'my_template' }"></div>

templateProperty

The templateProperty option provides the ability to specify a key that, if defined, will be used to check whether a given module has defined its own template. The result is a module that is fully self-contained (i.e. with no external templates). Take the following example:

<div data-bind="module: { name: 'my_module', templateProperty: 'template' }"></div>
define(['knockout'], function(ko) {

	return {

		'template': "<div>I have my own template.</div>"

	};

});

initializer

If the module returns an object (rather than a constructor function), then the binding will attempt to call an initializer function, if it exists. By default, this function is called initialize, but you can override the name of the function to call using this option or globally by setting ko.bindingHandlers.module.initializer to the name of the function that you want to use.

<div data-bind="module: { name: 'my_module', initializer: 'initialize' }"></div>

disposeMethod

When a module is swapped out, you can specify a custom function name to call to do any necessary clean up.

<div data-bind="module: { name: 'my_module', disposeMethod: 'dispose' }"></div>

afterRender

The afterRender function is passed on to the template binding. If a string is specified, then it will be used to find a method on the module itself. Otherwise, if a function reference is passed, then it will be used directly.

<div data-bind="module: { name: 'my_module', afterRender: 'afterRender' }"></div>

moveNodesToContext

The moveNodesToContext option will extract the children of the module binding and provide them as the $moduleTemplateNodes context property. This allows a module to act as a "wrapper" for the supplied nodes. The module's template would want to render the children using the template binding ( template: { nodes: $moduleTemplateNodes } ).

Module Binding - Global Options

There are a few options that can be set globally for convenience.

ko.bindingHandlers.module.baseDir (default: "")

The baseDir is used in building the path to use in the require statement. If your modules live in the modules directory, then you can specify it globally here.

ko.bindingHandlers.module.initializer (default: "initialize")

This allows the ability to globally override the function that the module binding calls after loading an AMD module that does not return a constructor.

ko.bindingHandlers.module.disposeMethod (default: "dispose")

The dispose method name can be globally overriden. This function is optionally called when a module is being removed/swapped.

ko.bindingHandlers.module.templateProperty (default: "")

The templateProperty option can be globally set. If defined, when a module is loaded - if it has a property with the key specified here (where the value is a string or function), the value of that property will be used as the template for the module. The result is a fully self-contained module (i.e. it has its own template, not an external one).

Dependencies

  • Knockout 2.0+

Examples

The examples directory contains a sample using require.js and using curl.js. For your convenience, you can quickly spin up an Express instance that serves these files by running:

$ node express

License

MIT license - http://www.opensource.org/licenses/mit-license.php

knockout-amd-helpers's People

Contributors

aw2basc avatar dependabot[bot] avatar mringer avatar mszynka avatar rniemeyer avatar sybeck2k avatar symunona avatar tkambler avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

knockout-amd-helpers's Issues

AfterRender not firing when module is initialized with a null observable

When the module data-binding is bound to an observable in the ViewModel and that ViewModel is originally set to null, changing the observable value afterward won't fire the afterRender callback.

Example in JSFiddle: http://jsfiddle.net/tvillaren/RA8Lf/2/ (initial code taken from #7).
Click on "Toggle" sets observable to a new module, but the afterRender callback is not called.

Possible Workaround:
The observable's default value can be set to

this.activeModule = ko.observable({
        name: null, 
        template: null, 
        afterRender: null
});

Following changes to the observable will fire the afterRender callback in that case.

API available in bonded module needs to be called after template finishes rendering

Hi, We are using this module binding extensively in our project. But we are facing a seems to be simple issue.

In module binding we are passing a function (view model) as the module to bind with. This module contains some API that needs to be triggered when provided template finishes rendering.

I did say "afterRender" configuration that we can pass, but then it expects fucntion provided as afterRender on parent module (on whose template this module binding lies). But our requirement to execute API of module (that is passed in the binding) to execute after template renders.

e.g

Here TestViewModel contains that API that needs to be executed after TestView finishes rendering.

Let me know if more info needed.

Thanks in advance

Provide simple way to load external templates from within custom bindings

In the current implementation of these helpers, composing the logic that loads external templates is a bit kludgy as I have to utilize the module binding handler in my custom binding in order to trigger the external loading. This comes with the cost of also defining a new AMD module in order to perform the simple template loading.

For example:

define([
    'knockout',
    'jquery',

    'vendor/js/blur'
], function (
    ko,
    $
) {
    'use strict';

    ko.bindingHandlers.templateWrapper = {
        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var $element = $(element);
            var bindingData = ko.unwrap(valueAccessor());

            // module binding requires an AMD module in order to load the template
            define('components/taco/TacoBindingModule', [], function () {
                return {
                    foo: ko.observable("taco")
                };
            });

            var accessor = function () {
                return {
                    name: 'components/taco/TacoBindingModule',
                    template: 'components/taco/tacoTemplate'
                };
            };

            ko.bindingHandlers.module.init(modalContainerNode, accessor, allBindings, viewModel, bindingContext);
        }
    };
});

it would be nice if I did not have to create a whole new AMD module to just load the template. Something like the following would make this much easier to do w/in a custom binding:

define([
    'knockout',
    'jquery',

    'vendor/js/blur'
], function (
    ko,
    $
) {
    'use strict';

    ko.bindingHandlers.templateWrapper = {
        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var $element = $(element);
            var bindingData = ko.unwrap(valueAccessor());

            var accessor = function () {
                return {
                    name: 'components/taco/TacoBindingModule',
                    template: 'components/taco/tacoTemplate',
                    date { foo: ko.observable("taco") }
                };
            };

            ko.bindingHandlers.module.init(modalContainerNode, accessor, allBindings, viewModel, bindingContext);
        }
    };
});

This way, it saves consumers the extra step of being required to define an AMD module. It would also help with making the template loading aspect of this library more composable with custom bindings as well as allowing custom bindings to create internal view models for their templates.

Module Binding: require() for the template source should not have to wait until the module is downloaded

With the current implementation, ko.templateSources.requireTemplate.prototype.text() will be executed only after templateBinding.data observable is mutated with a non-null value, i.e. when the module is downloaded and instantiated. That is when the 'if' condition on the underlying template binding will be satisfied.

The performance of the Module binding should improve significantly if the template source is downloaded in parallel with the module source. The init() function of the "module" binding can check whether the module name points to an external template, and execute a require() call without a callback. This will initiate the download of the template source before Knockout template is executed. amdTemplateEngine will execute require() for the template source exactly as it does today. Require.js will be smart enough to realize that download of the template source has already started (or perhaps is already done), and invoke the callback much sooner than it would have done if the download had to be initiated then.

afterRender still fires only for the first template when using external templates with requirejs/text

Hi!
I'm still encountering the problem that the afterRender callback gets called only once for the first template when using the template binding and loading external templates with requirejs/text.

It works when I use script tags as templates but when I load external templates using the AMD loader's text plugin the afterRender gets called only once. It also only happens when there are at least two different templates (when both templates in the following example have the same name the problem does not occur).

Here is an example of my (main) script code:

require.config({
    baseUrl: 'Scripts',
    paths: {
        knockout: '3rdparty/knockout-3.1.0.debug',
        koamdhelper: '3rdparty/knockout-amd-helpers',
        text: '3rdparty/text'
    }
});

require(['knockout', 'koamdhelper', 'text'], function (ko) {

    ko.amdTemplateEngine.defaultPath = "templates";
    ko.amdTemplateEngine.defaultSuffix = ".tmpl.html";
    ko.amdTemplateEngine.defaultRequireTextPluginName = "text";

var viewModel = {
    elements: ko.observableArray(),
    getTemplateName: function (item) {
        return item.template();
    },
    afterRender: function (domElement, item) {
        console.log(item);
    }
};

viewModel.elements.push({
    name: ko.observable("firstElement"),
    template: ko.observable("textboxTemplate")
});

viewModel.elements.push({
    name: ko.observable("secondElement"),
    template: ko.observable("textareaTemplate")
});

ko.applyBindings(viewModel);
});

and the html:
<div data-bind="template: { foreach: elements, name: getTemplateName, afterRender: afterRender }"></div>

I have two templates "textareaTemplate.tmpl.html" and "textboxTemplate.tmpl.html".

I also found out that the callback for name (getTemplateName in the above example) gets called twice for each element (four times instead of two times in the above example).

Passing data from Tempate to Module

Thanks for this great helper lib, it's awesome!

Is there a way to pass data from the tempate to the initializer of the module?

for example:

cars.html

<div data-bind="template: {name: 'car', brand: 'mazda'"></div>
<div data-bind="template: {name: 'car', brand: 'honda'"></div>

car.template.html

<div data-bind="module: { name: 'car' }">
*display stuff about a car*
</div>

car.js

define(['knockout'], function(ko) {

    var module = {};

    module.initialize = function(brand) {
        *setup the module for a particular car brand*
    };

    return module;
});

Ready to use KO module using requirejs "map"

Hello,

I was reading that article: http://blog.scottlogic.com/2014/02/28/developing-large-scale-knockoutjs-applications.html and I thought it made sense to use the map functionality of requirejs to have a fully loaded knockout module (i.e. with amd-helpers, customBindingHandlers and so on).

// require-config.js
var require = {
    paths: {
        'knockout-raw': 'lib/knockout.debug',
        'knockout-amd-helpers': 'lib/knockout-amd-helpers/build/knockout-amd-helpers',
    },
    shim: {
        'knockout-amd-helpers': {
            deps: ['knockout-raw'] // 17/05/2016 - Helper: ['knockout'] only is not working.
        },
    map: {
        '*': {
            'jquery': 'jquery-private',
            'knockout': 'knockout-extended'
        },
        'jquery-private': {
            'jquery': 'jquery'
        }
    }
};

// knockout-extended.js
define([
    'knockout-raw',
    'knockout-amd-helpers',
    'customBindingHandlers/foo',
    'customBindingHandlers/bar'
], function (ko) {
    ko.bindingHandlers.module.templateProperty = 'template';
    return ko;
});
// build.js
({
    name: '.path/to/almond',
    include: ['config', 'main'],
    mainConfigFile: './require-config.js',
    optimize: 'none',
    out: 'main-built.js'
})

However, knockout-amd-helpers already has a

// knockout-amd-helpers 0.7.4 | (c) 2015 Ryan Niemeyer |  http://www.opensource.org/licenses/mit-license
define(["knockout"], function(ko) {

and the output of r.js gives this for knockout base module:

        // [1] AMD anonymous module
        define('knockout-raw',['exports', 'require'], factory);

it results in an error at this line: https://github.com/rniemeyer/knockout-amd-helpers/blob/master/build/knockout-amd-helpers.js#L6

Would the only solution be to edit the code of knockout-amd-helper and set it to knockout-raw (which is working)?

SCRIPT5007: Function.prototype.apply error in IE8

When writing data-bind="module: { name: 'Modulename', data: initData }" IE8 throws a SCRIPT5007 error.This happens when optional args are undefined.

fixed it with:

Wrapper = function() {
if(args === undefined){
args = [];
};
return Constructor.apply(this, args);
};

on line 11 of knockout-amd-helpers.js

loading from html / js

hi,
when i include

<div data-bind="template: {name: 'home' }"></div>

it all works as expected!

But when I want to call

ko.renderTemplate('home',{}) 

directly from javascript the following is happening:

The call requires the 'home' template and starts downloading it.
But: the template is rendered before it is downloaded?!
So I end up with empty div tags.

But when I do something like this (with timeout) it starts working
(note: I am using knockback, instead of knockout here. but it also calls the ko.renderTemplate after doing some vodoo).

console.log(kb.renderTemplate('home', { }));
setTimeout(function(){
    console.log(kb.renderTemplate('home', {}));
}, 150)

the second console.log gives me the expected output. First one is empty div. (Timeout needs to be large enough here)

To further my problem description:

...I am trying to implement the knockback in a requirejs module
In the below snippet it needs to load the 'page' - template
(sample from here: https://github.com/kmalakoff/knockback-navigators)

router.route('', null, page_navigator.dispatcher(function(){
  page_navigator.loadPage( kb.renderTemplate('page', new PageViewModel(pages.get('main'))) );
}));

currently I am unable to make the kb.renderTemplate('page',{}) call work properly - because i don't want to include all my templates via script-tags.

Not sure if this is an issue of this plugin...
But if anybody can point me towards a solution, pls comment ;)

Getting the reference to the bound element

I am forking this so that I can get the bound element from within the constructor referenced via the 'module' data-binding. Are you interested in receiving this contribution?

renderTemplateSource produces an empty string

renderTemplateSource in Knockout calls the text function from the templateSource and then uses it right away to create HTML Elements.

nativeTemplateEngine.js#L15

This doesn't work with with the text function in Knockout AMD Helpers as the text is loaded asynchronously.

amdTemplateEngine.js#L24

And while that request is being made the current template is returned, which is an empty string.

amdTemplateEngine.js#L37

I tried to figure out if this could be corrected, but the function chain is synchronous.

Is there a work around for this?

I assume pre-loading the templates would work as long as I gave them enough time to return, but I'd rather have the lazy loading.

Another option might be creating renderTemplateSourceAsync. I don't think that would work with existing ko code, but it'd work for my use case.

not working with webpack very well.

I am getting the below error every time I build with webpack:

Critical dependency: the request of a dependency is an expression

Any ideas how this can be fixed?

Knockout-amd-helpers does not play well with r.js namespacing

Hi Guys,

I just ran into an issue where i use namespacing in my r.js setup (http://requirejs.org/docs/faq-advanced.html#rename). Chrome is giving me the exception:

app.js:2811 Uncaught TypeError: Unable to process binding "template: function (){return { name:"CatalogRequestSingle"} }"(โ€ฆ)

In version 0.7.4 require is taken from the window object. So i changed the code so that require is actually a dependency:

define(["knockout", 'require'], function (ko, require){

And now it works!

Is there a better way to do this? Or is my change just fine?

Bubbling up an event from within a module for the parent to handle / take some action on.

Hi Ryan,

Quick question.Here's my setup again-

//parent page Html
<div data-bind="module: moduleInfo"></div>

//parent view model
this.moduleInfo=ko.observable(
{ data: "",
  disposeMethod: "dispose",
  id: "moduleId",
  initializer: "initialize",
  name: "modulevm",
  template: "moduleTmpl"
}
);

//module's view model - modulevm
//function that handles a button click event
this.ButtonClick=new function(){
//Do some work.
//How do I let parent know of this event?
}

Is there a recommended way of doing this? Any thoughts / suggestions?

[Request] Option to require additional files by convention

Would be nice to be able to configure additional requires by convention. So "module: 'MyModule'" could additionally require "css!styles/MyModule" or "less!styles/MyModule", here used with the require-css or require-less modules.
That way styles for views can be loaded automatically without creating a dependency in the viewmodel.

At it simplest it could just be a hook every time template or module is used.

Dynamically assigning a template path in renderTemplate()

I wonder if there is a way to do something like this:
ko.renderTemplate( 'tplName', myViewModel, { path: '/app/templates/custom/XYZ' }, this, "replaceNode" );
I mean, if there is a way to re-write ko.amdTemplateEngine.defaultPath on the fly?

Module 'initializer' fires twice

I'm currently working on a SPA project with multiple views (each having its own view model).The application is setup with hash based navigation using SammyJS. Based on the hash requested, a view /view model combination gets activated (dynamic module binding using 'ko amd helpers').

I'm noticing inconsistencies where the 'initializer' method defined on a module gets fired twice when the browser back button is used. I'm also seeing the same behavior when debugging the project in Visual Studio 2012.

Any thoughts on this? Has this been reported before?

knockout-amd-helpers need new typings

knockout 3.5.0 now ships with new knockout typings inside knockout npm package. This is no longer compatible with "@types/knockout-amd-helpers".
Can either "@types/knockout-amd-helpers" be updated or can you add new typings that would be inside the npm package as well?

afterRender-method inside view model

While we do have the auto-executed initialize-method inside the view model of a module, this is executed before the template was successfully rendered. What I need (and I'd guess others would, too) would be an easy way to have an afterRender-method inside the view model. Relaying this event from inside the parent view model to the child model gets really tedious, especially when one has multiple modules on one page.
I tried to implement it myself, but my approach is more or less a hack (which doesn't even work right at the moment ;) )

benefitting from the requirejs-optimizer

Hi,
I am bundling all my JavaScript files into a single file via the require.js optimizer. Unfortunately, while I was successful in including html-templates, those were not used by this library and were still being downloaded one by one.

Is there a specific setting or a guideline/naming one has to follow for that to function?

Regards,
nmehlei

Integration with other text-based templating engines

First off, just like to comment that I love the simplicity and the integration point with requirejs of this knockout plugin.

I noticed that since this is overriding the template binding, it would effectively block any other knockout templating engines from working - is that true (I'm no expert on ko internals)?

Do you see supporting other text-based templating engines as something pluggable and within the scope of knockout-amd-helpers? The utilization of require's text plugin is a great way to integrate with other templates engines.

Thanks

Working with Typescript AMD Modules

I would love to see an example of this. It all loads, but I find that the default template engine is not being replaced when it gets to my viewmodel in another module, and tries to use the template binding to render the view. A working example would be great.

Accessing module binding information from within a module

Hi Ryan,
Quick question - I've been using dynamic module binding (using 'ko amd helpers') in my project and I've run into a situation where I think I need to be able to access module binding information from within a module's view model.

For example -

//Html
<div data-bind="module: moduleInfo"></div>

//parent view model
this.moduleInfo=ko.observable(
{ data: "",
  disposeMethod: "dispose",
  id: "moduleId",
  initializer: "initialize",
  name: "modulevm",
  template: "moduleTmpl"
}
);

//module's view model - modulevm
//have a need to access the 'id' of the module from within 'dispose'.

As you can see, I've attributes other than the standard ones needed for the amd plugin. I am looking to get the 'id' value from within the 'dispose' method of the module. Is there a way to accomplish this.

module and template loaders don't work with require.config moduleIDs packages

It looks like the problem is related to

line:117

require([addTrailingSlash(ko.bindingHandlers.module.baseDir) + moduleName], function(mod) {

& line:177

templatePath = engine.defaultRequireTextPluginName + "!" + addTrailingSlash(engine.defaultPath) + this.key + engine.defaultSuffix;
require([templatePath], this.template);

Where if the default path were not always added, the a [require.js package][http://requirejs.org/docs/api.html#packages] would load as defined by the projects require.config, however using this pattern limits the options of integrating with the projects config, and as such my modules and templates are not loading correctly.

I'm considering a fix that would add a ko.amdTemplateEngine.defaultConfig = true that would basically use the projects default moduleID resolution methods, instead of prepending the default path.

Thinking out-loud hear, maybe each bind/module.options should allow for a different default on moduleID search path, some might want to use one pattern for some modules, and another pattern for other modules.

thoughts?

PS. I don't need this feature now but some projects will have multiple require configs, under unique require.contexts, which for example could generate two require references, ex. requireOne() for require context one, and requireTwo() for the second require context

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.