<commit_before># ampersand-view

A set of common helpers and conventions for using as a base view for humanjs / backbone applications.

<!---starthide-->
<p class="docLink">Part of the <a href="http://docs.humanjavascript.com/#all_human_view">Human JavaScript toolkit</a></p>
<!---endhide-->

What does it do?

1. Gives you a proven pattern for managing/binding the contents of an element.
2. Simple declarative property/template bindings without needing to include a template engine that does it for you. This keeps your logic out of your templates and lets you use a string of HTML as a fully dynamic template or just a simple function that returns an HTML string.
3. The view's base element is replaced (or created) during a render. So, rather than having to specify tag type and attributes in javascript in the view definition you can just include that in your template like everything else.
4. A way to render a collection of models within an element in the view, each with their own view, preserving order, and doing proper cleanup when the main view is removed.
5. A simple way to render sub-views that get cleaned up when the parent view is removed.


## Install

```
npm install ampersand-view
```

## Usage

### Basics

Nothing special is required, just use `AmpersandView` in the same way as you would Backbone.View:

```javascript
var MyView = AmpersandView.extend({
    initialize: function () { ... }, 
    render: function () { ... }
});
```

### Declarative Bindings

```javascript
var MyView = AmpersandView.extend({
    // set a `template` property of your view. This can either be
    // a function that returns an HTML string or just a string if 
    // no logic is required.
    template: '<li><a><span class="userName"></span></a></li>', 
    // Simple declarative bindings
    // The key is the name of the model property
    bindings: {
        // the value is a selector, by default a text binding is assumed
        // this would keep the model's `name` attribute in the span, even
        // if it's changed.
        name: '.userName',
        
        // If the `active` property is a boolean the class 
        // will be added/removed based on the boolean property.
        // But, if the `active` property were a string, the previous
        // value would be removed and the new one added from the class
        // list without affecting other classes that may alreay be there.
        active: ['li', 'class'],
        
        // If you've got a boolean property, you can also specify a third
        // item in the array. It will be used to determine what the class
        // is that will be toggled. This way your property name can be 
        // different than the class. 
        isActive: ['li', 'class', 'active'], // will toggle the 'active' class
        
        // If you prefer, you *can* also bind to the whole class list. Which
        // will wipe out all existing classes.
        myClasses: ['li', 'classList'],

        // As you might have guessed, you can bind to any attribute you want
        userUrl: ['a', 'href'],

        // This works for boolean attributes. The following would add and remove 
        // the entire `checked` attribute (assuming the property value was a boolean)
        selected: ['input', 'checked']

        // If you really need to, you can even bind the same attribute to different
        // types of things with different options. If "superActive" was a string, the following would put
        // the text value of it, inside `.userName` and add it as a class on the `li`.
        superActive: [
            // the *only* restriction here is that if you pass an array of binding
            // declarations for a single property, each sub-item must also be an
            // array.
            ['.userName'],
            ['li', 'class'],
            // you can even get crazy... this would bind both
            // data attributes to both the li and .username elements
            ['li, .username', 'data-attribute1 data-attribute2'],
        ]        
    },
    render: function () {
        // method for rendering the view's template and binding all
        // the model properties as described by `textBindings` above.
        // You can also bind other attributes, and if you're using
        // human-model, you can bind derived properties too.
        this.renderAndBind({what: 'some context object for the template'});
    }
});
```


### What about two-way bindings?

Note that these are all one-way bindings. People love to talk about the feature of two-way bindings, but from my experience, the vast majority of the time it's not actually something that you want. Why make two different ways of doing the same thing? The most common two-way bindings that people do are for form elements, which, is super easy to do with the events hash. Plus, then it's very easy to configure exactly when you want the user action to actually change the model.

Having said that, we may enable it anyway, in a future release, that's still up for discussion.

<commit_msg>updating readme with correct link<commit_after># ampersand-view

A set of common helpers and conventions for using as a base view for ampersand.js apps.

What does it do?

1. Gives you a proven pattern for managing/binding the contents of an element.
2. Simple declarative property/template bindings without needing to include a template engine that does it for you. This keeps your logic out of your templates and lets you use a string of HTML as a fully dynamic template or just a simple function that returns an HTML string.
3. The view's base element is replaced (or created) during a render. So, rather than having to specify tag type and attributes in javascript in the view definition you can just include that in your template like everything else.
4. A way to render a collection of models within an element in the view, each with their own view, preserving order, and doing proper cleanup when the main view is removed.
5. A simple way to render sub-views that get cleaned up when the parent view is removed.

<!-- starthide -->
Part of the [Ampersand.js toolkit](http://ampersandjs.com) for building clientside applications.
<!-- endhide -->

## Install

```
npm install ampersand-view
```

## Usage

### Basics

Nothing special is required, just use `AmpersandView` in the same way as you would Backbone.View:

```javascript
var MyView = AmpersandView.extend({
    initialize: function () { ... }, 
    render: function () { ... }
});
```

### Declarative Bindings

```javascript
var MyView = AmpersandView.extend({
    // set a `template` property of your view. This can either be
    // a function that returns an HTML string or just a string if 
    // no logic is required.
    template: '<li><a><span class="userName"></span></a></li>', 
    // Simple declarative bindings
    // The key is the name of the model property
    bindings: {
        // the value is a selector, by default a text binding is assumed
        // this would keep the model's `name` attribute in the span, even
        // if it's changed.
        name: '.userName',
        
        // If the `active` property is a boolean the class 
        // will be added/removed based on the boolean property.
        // But, if the `active` property were a string, the previous
        // value would be removed and the new one added from the class
        // list without affecting other classes that may alreay be there.
        active: ['li', 'class'],
        
        // If you've got a boolean property, you can also specify a third
        // item in the array. It will be used to determine what the class
        // is that will be toggled. This way your property name can be 
        // different than the class. 
        isActive: ['li', 'class', 'active'], // will toggle the 'active' class
        
        // If you prefer, you *can* also bind to the whole class list. Which
        // will wipe out all existing classes.
        myClasses: ['li', 'classList'],

        // As you might have guessed, you can bind to any attribute you want
        userUrl: ['a', 'href'],

        // This works for boolean attributes. The following would add and remove 
        // the entire `checked` attribute (assuming the property value was a boolean)
        selected: ['input', 'checked']

        // If you really need to, you can even bind the same attribute to different
        // types of things with different options. If "superActive" was a string, the following would put
        // the text value of it, inside `.userName` and add it as a class on the `li`.
        superActive: [
            // the *only* restriction here is that if you pass an array of binding
            // declarations for a single property, each sub-item must also be an
            // array.
            ['.userName'],
            ['li', 'class'],
            // you can even get crazy... this would bind both
            // data attributes to both the li and .username elements
            ['li, .username', 'data-attribute1 data-attribute2'],
        ]        
    },
    render: function () {
        // method for rendering the view's template and binding all
        // the model properties as described by `textBindings` above.
        // You can also bind other attributes, and if you're using
        // ampersand-model, you can bind derived properties too.
        this.renderAndBind({what: 'some context object for the template'});
    }
});
```


### What about two-way bindings?

Note that these are all one-way bindings. People love to talk about the feature of two-way bindings, but from my experience, the vast majority of the time it's not actually something that you want. Why make two different ways of doing the same thing? The most common two-way bindings that people do are for form elements, which, is super easy to do with the events hash. Plus, then it's very easy to configure exactly when you want the user action to actually change the model.

Having said that, we may enable it anyway, in a future release, that's still up for discussion.


{'fraction_non_alphanumeric': 0.08138382236320381, 'fraction_numerical': 0.0013877874702616971, 'mean_word_length': 2.6252245777937477, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1609745', 'n_tokens_mistral': 2547, 'n_tokens_neox': 2464, 'n_words': 1400}