简体   繁体   中英

Bind dynamically loaded checkbox to Angular.js model

I am using Angular.js and DataTables to load a big list of data. This is using server side processing, so the page is loaded, and then the DataTable loads.

My table has two columns of checkboxes that I am trying to bind to an angular root scope variable. Here is the code where I set my rootscope variable as a placeholder.

ultModule.run(function($rootScope) {
    $rootScope.report = {
        disavow: { domains: [], urls: [] }
    };
});

The following function is called by my controller to retrieve the saved data and to save the reason variable in the report.disavow (checkbox data to save) object.

function setSelectionData($rootScope, $http) {
    /* Checkbox Initial Data */
    $http({
        method: 'POST', 
        url: '../ajax-targets/get-report-selected.php',
        data : { 'id': $rootScope.report.id }
    }).success(function(data, status, headers, config) {
        if(data.error) { alert(data.msg); }
        $rootScope.report.disavow = data;
    }).error(function(data, status, headers, config) {
        alert('There was an error starting the process. Please try again later.');
    });

    /* Checkbox Handeling */
    $rootScope.toggelSelected = function(type, id, reason) {
        if(type === 'domain') {
            $rootScope.disavow.domains[id].reason = reason;
        } else {
            $rootScope.disavow.urls[id].reason = reason;
        }
        var a = $rootScope.disavow;
    }
}

ultController.controller('CtrlReportStats', function($rootScope, $scope, $routeParams, $http) {
    setRootScopeParams($rootScope, $http, $routeParams.reportSha);
});

This is an example of the checkbox that I would like to bind to the report.disavow object.

<input type="checkbox" data-ng-model="report.disavow.domains[20378].checked" data-ng-change="toggelSelected('20378', 'url', 'bad-link')">

This code works perfectly if I paste the checkbox tag (above) into the partial.html. If I return this and put it in the datatable it doesn't do anything.

I believe that I need to tell Angular to check the page again and bind to any objects. I'm looking through the docs but haven't found what I'm looking for. Can anyone point me in the right direction? Please and thank you.

All right I have found my answer. All of my above code for the checkbox's is correct.

The issue was that Angular doesn't automatically bind directives and models to html added to the dom element after page load, which DataTables does.

The solution was to use $compile to parse the html and fnLink to binde it to the $scope. Please note that I am using $rootScope to maintain a list across multiple pages. In most cases you would probably want $scope.

function setupForAngular($rootScope, $compile) {
    return function(element) {
        var fnLink = $compile(element);     // returns a Link function used to bind template to the scope
        fnLink($rootScope);                 // Bind Scope to the template
    }
}

And here's my controller.

app.controller('CtrlChecks', function($rootScope, $scope, $compile) {
    var activateInAngular = setupForAngular($rootScope, $compile);

    $scope.options = {
        sDom: '<"top"lif>rt<"bottom"lip><"clearfix">',
        aaSorting: [[ 3, "desc" ]],
        aLengthMenu: [[100, 250, 500, 1000, 1500, 2000, 2500, -1], [100, 250, 500, 1000, 1500, 2000, 2500, "All"]],
        iDisplayLength: 100,
        sPaginationType: "full_numbers",
        bSort: true,
        bAutoWidth: false,
        oLanguage: { "sEmptyTable": 'No patterns found' },
        bProcessing: true,
        bServerSide: true
    };
    $scope.options.sAjaxSource = '../ajax-targets/get-domains.php';
    $scope.options.fnRowCallback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
        $(nRow).attr('id', aData['id']);
        setupDetailClickEvent(nRow, activateInAngular);
    }
    $scope.options.fnInitComplete = function(oSettings, json) {
        activateInAngular(this);
    }
    $scope.options = buildDataTable(activateInAngular);
    $scope.options.fnServerParams = function(aoData) {
        aoData.push({"name": "type", "value": "dead"}, {"name": "id_sha", "value": $rootScope.report.sha});
    };
    $scope.options.aoColumns = [
        {"mDataProp": "index", "sClass": "index"},
        {"mDataProp": "check-box-domain", "sClass": "check-box"},
        {"mDataProp": "check-box-url", "sClass": "check-box"},
        {"mDataProp": "pageLink", "sClass": "pageLink"},
        {"mDataProp": "reason_text", "sClass": "reason"}
    ];
    $scope.options.aoColumnDefs = [{"bSortable": false, "aTargets": [0, 1, 2]}];
    $scope.counter = 0;
});

Heres some links to docs:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM