用可重复使用的角度指令包装jquery灯箱

时间:2016-03-01 13:31:23

标签: javascript jquery angularjs

我正在尝试在angular指令中包装一个自定义的jquery灯箱。我不想触摸jquery代码,因为它也用于非角度项目,但我想提供一个很好的Angular指令,使得使用它更容易。

经过一段时间的努力,我意识到我可能想要这样的东西:

var t = $( ".datatable-1" ).DataTable({
    "iDisplayLength": 30});

这里的一些问题是ng-click需要调用灯箱中的功能(已经解决),通过隔离范围将一些配置传递到灯箱,并在此灯箱必须工作时传递条件(仅适用于待完成的工作)。奇怪的是,弹出条件不会最终出现在灯箱的链接功能中。到那时,整个<tr ng-repeat="job in ctrl.jobs" ng-click="lightbox.open()"> <lightbox-popup api="lightbox" popup-condition="job.status == 'pending'" popup-options="{buttons: {confirm:'OK',cancel:'cancel'}}"> <custom-popup-content data="job"/> </lightbox-popup> <td ng-repeat="tableColumn in ctrl.columnNames">{{ job[tableColumn] }} </td> </tr> 属性不再存在。也许是因为同时创建了一个新的隔离范围?但我应该能够像这样通过job,不是吗?

(我还没有工作的plnkr,因为我必须对很多代码进行匿名处理,在某些时候,即使我工作的东西也停止工作。)

lightbox指令看起来有点像这样:

job

我希望有人知道为什么我的popupCondition不再起作用了。

(它曾经在我的代码的一个更丑陋的版本中工作,它使用了app.directive('lightboxPopup', function ($compile) { var box = require('fg/lightbox'); // this is our custom jquery lightbox var defaultSettings = { title: 'Popup title', buttons: { confirm: 'OK' }}; return { scope: { popupCondition: '=', popupOptions: '=', api: '=' }, link: function (scope, element, attrs) { function openLightbox() { console.log("popupOptions: ",scope.popupOptions); // works console.log("popupCondition: ",scope.popupCondition); // false, because job mysteriously doesn't exist if (scope.popupCondition === true) { var settings = angular.extend(defaultSettings, scope.popupOptions); console.log("settings: ",settings); element.bind('click', function () { var popup = box(settings).setHtml(element).open(); }); } } scope.api = { open: openLightbox }; } }; }); ,哪种工作,但我觉得这很难看。)

1 个答案:

答案 0 :(得分:0)

我害怕我采用了丑陋的方法。我仍然在寻找一种更好的方法,但是这段代码可以工作:

app.directive('lightboxPopup', function ($compile) {
    var box = require('fg/lightbox'); // our custom jquery lightbox

    var defaultSettings = {
        title: 'Popup',
        buttons: {
            confirm: 'OK'
        }};

    var directiveSettings = {};

    function lightboxSettings(settings) {
        directiveSettings = settings;
    }

    return {
        scope: {
            popupCondition: '=',
            popupDirective: '@lightboxPopup',
            popupData: '='
        },
        link: function (scope, element, attrs) {
            if (scope.popupCondition === true) {
                scope[attrs.popupData] = scope.popupData;
                scope.lightboxSettings = lightboxSettings;
                var el = $compile( "<"+scope.popupDirective+"></"+scope.popupDirective+">" )( scope );
                element.bind('click', function () {
                    var settings = angular.extend(defaultSettings, directiveSettings, scope.popupOptions);
                    var popup = box(settings).setHtml(el).open();
                });
            }
        }
    };
});

使用范围和数据来确保弹出窗口内容的指令可以访问所需的数据,并且可以从该指令访问api以注册自己的回调,在我看来非常可怕。但它确实有效。

<tr ng-repeat="job in ctrl.jobs" lightbox-popup="popup-content-directive" popup-condition="job.status == 'pending'" popup-data="job">
    <td ng-repeat="tableColumn in ctrl.columnNames">{{ job[tableColumn] }} </td>
</tr>

带内容的included指令会像下面这样注册其lightbox配置:

app.directive('popupContentDirective', function (updateService) {

    return {
        link: function (scope, element, attrs) {
            scope.lightboxSettings({
                title: "Update job",
                buttons: {
                    cancel: "cancel",
                    confirm: "OK"
                },
                confirm: function() {
                    updateService.update(scope.job);
                }
            });
        },
        templateUrl: 'partials/popupContentDirective.html'
    };
});

也可以从视图中覆盖设置。总而言之,功能是我想要的,但我认为应该有一个更清洁,更漂亮的方式来做到这一点,所以如果你有一个更好的答案,请发布。