简体   繁体   中英

AngularJS- how to display a button in a table cell?

I recently took over the development of an AngularJS application created by my company, and am currently trying to add a button to a cell in a table, which the user will be able to use as a navigation button, and set the location it directs you to as any one of the user's custom pages.

In the table directive, I have added the following code:

.directive('appTable', function(fxTag) {
    return {
        ...
        template: '...',
        controller: function($scope, $element, $compile, Global, fxEvent, fxSearch, NotifyMgr) {
            ...
            var goToPageBtnTmpl = $compile(
                '<a href="javascript:;" ng-click="goToPage(target)"' +
                '<class="btn btn-xs btn-brand">Go to Page</a>'
            );
            console.log("goToPageBtnTmpl defined: ", goToPageBtnTmpl);
            ...
            var goToPage = function(target) {
                // Code to navigate to the page set by the user
                console.log("goToPage button added: ");
            };
            ...
        }
    }
})

and in ctrl.js, there is a toWidgetObj() function, which creates a widget based on the details that the user selects/ enters on a form:

}).controller('WidgetPickerCtrl', function($scope, $timeout, fxTag, gPresets, appWidget, appUI, pagesPresets) {
    ...
    function toWidgetObj() {
        ...
        var widgetObj = {
            name: $scope.widget.name,
            label: $scope.widget.label,
            attr: angular.copy($scope.widget)
        };

        switch(widgetObj.name) {
            case 'app-table':
                ...
                angular.forEach(widgetObj.table.rows, function(row) {
                    if(row.length > 0) {
                        reducedRows.push(row.map(
                            function(tag) {
                                if(tag.isTag) {
                                    return {tag: tag.tag, nounit: tag.nounit};
                                }
                                if(tag.isBtn) {
                                    var goToPageBtnTmpl = $compile(
                                        '<a href="javascript:;" ng-click=goToPage(target)"' + 'class= "btn btn-xs btn-brand">Go to page</a>'
                                    )
                                }
                            }
                        ));
                    }
                });
                ...
                break;
            ...
        }
        ...
        return widgetObj;
    }
    ...
});

When I currently click the 'Edit widget' button on a table widget, the 'Edit Widget dialog is opened, and I add a button to a cell in the table. When I then click the 'Preview' button, to update the widget with the changes I have entered in the dialog, I see the print statement from the directive displayed:

goToPageBtnTmpl defined: publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn){ assertArg(scope, 'scope');

and I am expecting the table to show a the button that has been compiled by the line:

var goToPageBtnTmpl = $compile(
    '<a href="javascript:;" ng-click="goToPage(target)"' +
    'class = "btn btn-xs btn-brand">Go to page</a>'
)

that will take the user to the page whose address I specified in the input on the dialog.

But what I actually see when I click 'Preview' is the table displayed, and the cell where the button should be displayed is actually showing the link that I typed (ie the address of the page I am expecting it to take the user to when clicked).

My debug in the console is stating that the button has been added successfully:

Tag is a button:

{tag: "pages/userpage1", isTag: false, isBtn: true, nounit: false, units: undefined} isBtn : true isTag : false nounit : false tag : "pages/userpage1" units : undefined

but I don't actually see the button displayed on the page.

Anyone have any suggestions what I'm doing wrong here?

Edit

So, as I've looked into this further, I think I may have found the reason that the button is not displayed: the code where the button is compiled is written in the table directive's controller function:

.directive('appTable', function(fxTag) {
    return {
        ...
        controller: function(...) {
            ...
            var gotToPageBtnTmpl = $compile(
                ...
            );

So this is run when the page first loads. However, I am trying to add the button to the table manually, after the page has already loaded, and the code I'm using to do this is written later in the same controller function:

            if(!$scope.noTagAlarm()) {
                angular.forEach($scope.config.columns, function(col) {
                    ...
                    if(col.header.startsWith(":")) {
                        angular.forEach($scope.config.rows, function(row) {
                            col.template = function(value, row, metadata) {
                                goToPageBtnTmpl(value);
                            }
                        })
                    }else{
                        console.log("column doesn't start with ':' ");
                    }
                    ...
                });
            }

My thought is that since this code is written in the directive's controller function, it is probably only run when the page is first loaded, and not when I edit the widget using my 'edit widget' dialog, so the HTML is not rendered.

Would that be the case? If so, how can I reload the widget after editing it without refreshing the whole page? Or, if not, what am I actually doing wrong here?

The issue here was that the function used in the col.template needed to return the button I wanted to create:

col.template = function(value, row, metadata) {
    return [
        umWidget.getBtnTmpl(
            $scope.$new(true),
            goToPage,
            value,
            value)
    ];
}

I defined the getBtnTmpl() function in Widget/service.js with:

function getBtnTmpl(scope, fn, target, title) {
    scope.fn = fn;
    scope.target = target
    var pageTitle = title.split('/');
    scope.title = pageTitle[1];

    return btnTmpl(scope);
}

and set btnTmpl as a global variable in Widget/service.js with:

var btnTmpl = $compile(
    '<a href="javascript:;" ng-click="fn(target)"' +
    'class="btn btn-xs btn-brand">{{title}}</a>'
);

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