2017-02-03 6 views
1

У меня есть страница с блоками информации, которые вы можете включить и выключить. Чтобы узнать, какие блоки вы хотите показать, я сохранил их состояние в Угловом файле cookie.Персонализация страницы с использованием 1 углового файла cookie

HTML:

<block-toggle-btn block-ref="{{ id }}" climbnodes="3" mytarget=".block__content"></block-toggle-btn> 

Угловая Директива:

myApp.directive('blockToggleBtn', ['$cookies', function($cookies) { 

return { 
    restrict: 'E', 
    template:'-', 
    link: link, 
    scope: { 
     blockRef: '@', 
     mytarget: '@', // target .cssclass 
     climbnodes: '=' // Used to climb the dom 
    } 
}; 

function link(scope, element, attr) { 
    var parent = element.parent(); 
    for (var i = 0; i < scope.climbnodes; i++) { 
     parent = parent.parent(); 
    } 

    var blockRef = scope.blockRef; 
    var blockToggleCookie = $cookies.get(blockRef); 

    scope.toggleVisibility = function() { 

     element.toggleClass('invisible'); 
     parent.find(scope.mytarget).slideToggle(); 

     if (element.hasClass('invisible')) { 
      element.html('+'); 
      blockVisible = 'invisible'; 
      scope.setBlockToggleCookie(blockRef, blockVisible); 
     } else { 
      element.html('-'); 
      blockVisible = 'visible'; 
      scope.setBlockToggleCookie(blockRef, blockVisible);  
     } 

    }; 

    scope.setBlockToggleCookie = function(blockRef, blockVisible) { 
     var expireDate = new Date(); 
     expireDate.setTime(2144232732000); 
     $cookies.put(blockRef, blockVisible, {'expires': expireDate}); 
    }; 

    // If cookie is set keep block closed 
    if (blockToggleCookie == 'invisible') { 
     scope.toggleVisibility(); 
    } 

    element.bind('click', function(event) { 
     event.preventDefault();    
     scope.toggleVisibility(); 
    }); 

} 

}]); 

Это отлично работает на данный момент, но он устанавливает куки для каждого "блока" информации я показываю. Мне нужно, вместо этого, переместить все это в один файл cookie, содержащий информацию о том, какие блоки показывать и что скрывать.

Я знаю, это звучит как большой вопрос, и это так, но я полагал, что было бы более полезно публиковать все это, а не каждую часть, с которой я борюсь, чтобы я мог лучше понять и собрать все это вместе. В настоящее время я сбился с кроличьей дыры, пытаясь понять, как создать массив объектов для хранения в Угловом $cookies.putObject. Я получаю странные результаты, когда я пытаюсь сделать .push() в массив объектов. Например, с помощью этой функции я попытался вызвать из события щелчка:

 scope.buildCookieObj = function(blockRef, blockVisible) { 
      scope.cookieItems.push({blockRef: blockRef, blockVisible: blockVisible}); 
     }; 

Я знаю, что это не является услугой написания кода, и я действительно пытался сделать этот шаг за шагом, но обнаружил, что потерял в сорняках , Я новичок в Angular и знаю, когда он его использует, или вставлять JQuery становится немного подавляющим. Поэтому даже любые советы о направлении принять это приветствуются.

EDIT:

Я думаю, что я сделал некоторый прогресс (хотя это уже поздно, так что я не совсем 100% это работает, но я так думаю). Это обновленный код, устанавливающий объект cookie. Теперь мне просто нужно извлечь и перебрать его, чтобы определить (из файла cookie), изначально блоки которых должны быть закрыты.

myApp.directive('blockToggleBtn', ['$cookies', function($cookies) { 

var cookieItems = []; 

return { 
    restrict: 'E', 
    template:'-', 
    link: link, 
    scope: { 
     blockRef: '@', 
     mytarget: '@', // target .cssclass 
     climbnodes: '=' // Used to climb the dom 
    } 
}; 

function link(scope, element, attr) { 
    var parent = element.parent(); 
    for (var i = 0; i < scope.climbnodes; i++) { 
     parent = parent.parent(); 
    } 



    scope.toggleVisibility = function() { 

     element.toggleClass('invisible'); 
     parent.find(scope.mytarget).slideToggle(); 

     if (element.hasClass('invisible')) { 
      element.html('+'); 
      blockVisible = 'invisible'; 
      scope.buildCookieObj(blockRef, blockVisible); 
     } else { 
      element.html('-'); 
      blockVisible = 'visible'; 
      scope.buildCookieObj(blockRef, blockVisible);  
     } 
    }; 

    scope.buildCookieObj = function(blockRef, blockVisible) { 
     // If that item already exists remove so we can replace with new visibility setting 
     $.each(cookieItems, function(i){ 
      if(cookieItems[i].blockRef === blockRef) { 
       cookieItems.splice(i,1); 
       return false; 
      } 
     }); 
     cookieItems.push({blockRef: blockRef, blockVisible: blockVisible}); 
     scope.setBlockToggleCookie(cookieItems); 
    }; 

    scope.setBlockToggleCookie = function(cookieItems) { 

     // Maximum value for cookie expiration, i.e. the closest thing to 
     // "never expire" is the year 2038. See: 
     // http://stackoverflow.com/questions/532635/javascript-cookie-with-no-expiration-date/532638#532638 and 
     // http://stackoverflow.com/questions/34586494/make-cookies-never-expire-with-angularjs 
     var expireDate = new Date(); 
     expireDate.setTime(2144232732000); 
     $cookies.putObject('personalization', cookieItems, {'expires': expireDate}); 
    }; 

    element.bind('click', function(event) { 
     event.preventDefault(); 
     scope.toggleVisibility(); 
    }); 

} 
}]); 

Дальнейший прогресс, за исключением противоположности действительно:

Реализованных У меня есть дополнительная проблема настройки куки в том, что он получает перезаписан каждый раз, когда вы вновь открыть приложение и переключение блоков и выключение. Все еще пытаюсь продумать эту логику. Если я назову его чем-то зависимым от времени или сеанса, а что нет, не уверен, как я тогда извлечу это, чтобы перебрать его.

Что касается извлечения печенья и установив соответствующие блоки, которые будут включаться и выключаться, я сделал это, чтобы получить значения:

var personalizationCookie = $cookies.getObject('personalization'); 
console.log(personalizationCookie); 

$.each(personalizationCookie, function(key, value) { 
    var blockRef = value.blockRef; 
    var blockVisible = value.blockVisible; 
    console.log(blockRef, blockVisible); 
}); 

Но я не понял, как целевые блоки , Я подумал, что, возможно, просто JQuery .find(), но я думаю, что dom еще не отображен, поэтому он ничего не находит. Обернуть его в $(document).ready() не работает. Я предполагаю, потому что у нас есть экран загрузки, который будет «загружен», даже если элементы dom, которые я ищу, по-прежнему не являются. Но это может быть что-то особенное для нашего приложения. Я должен спросить начальных разработчиков. Просто подумал, что я обновляю здесь всю информацию.

EDIT # 2: Так что я придумал решение, которое работает, и я подумал о «отвечая» на мой вопрос здесь, но решение, которое я придумал еще нуждается в некоторой доработке. Вся логика находится в директиве, и я знаю, что это не так, как должно быть.Я сказал, что хотел бы опубликовать его здесь, если это было полезно для всех, а также потому, что я работаю над тем, чтобы переместить всю логику в сервисы и приветствовал бы любое направление с этим. (Я уже вниз службы против завода вопрос отверстие, и это достаточно сложная, даже начав реальную задачу!)

myApp.directive('blockToggleBtn', ['$cookies', function($cookies) { 
var personalizationCookie = $cookies.getObject('personalization'); 

return { 
    restrict: 'E', 
    template:'-', 
    link: link, 
    scope: { 
     blockRef: '@', 
     mytarget: '@', // target .cssclass 
     climbnodes: '=' // Used to climb the dom 
    } 
}; 

function link(scope, element, attr) { 

    var parent = element.parent(); 
    for (var i = 0; i < scope.climbnodes; i++) { 
     parent = parent.parent(); 
    } 

    var blockRef = scope.blockRef; 

    scope.toggleVisibility = function() { 
     element.toggleClass('invisible'); 
     parent.find(scope.mytarget).slideToggle(); 

     if (element.hasClass('invisible')) { 
      element.html('+'); 
      blockVisibility = 'invisible'; 
      scope.buildCookieObj(blockRef, blockVisibility); 
     } else { 
      element.html('-'); 
      blockVisibility = 'visible'; 
      scope.buildCookieObj(blockRef, blockVisibility); 
     } 
    }; 

    scope.buildCookieObj = function(blockRef, blockVisibility) { 
     // If that item already exists remove so we can replace with new visibility setting 
     $.each(personalizationCookie, function(i){ 
      if(personalizationCookie[i].blockRef === blockRef) { 
       personalizationCookie.splice(i,1); 
       return false; 
      } 
     }); 
     personalizationCookie.push({blockRef: blockRef, blockVisibility: blockVisibility}); 
     scope.setBlockToggleCookie(personalizationCookie); 
    }; 

    scope.setBlockToggleCookie = function(personalizationCookie) { 

     // Maximum value for cookie expiration, i.e. the closest thing to 
     // "never expire" is the year 2038. See: 
     // http://stackoverflow.com/questions/532635/javascript-cookie-with-no-expiration-date/532638#532638 and 
     // http://stackoverflow.com/questions/34586494/make-cookies-never-expire-with-angularjs 
     var expireDate = new Date(); 
     expireDate.setTime(2144232732000); 
     $cookies.putObject('personalization', personalizationCookie, {'expires': expireDate}); 
     var personalizationCookie = $cookies.getObject('personalization'); 
    }; 

    // Check to see if there's a cookie for this element's block 
    // If yes, then toggle minus to plus and hide the block content the button refers to 
    $.each(personalizationCookie, function(key, value) { 
     if ((value.blockRef == scope.blockRef) && (value.blockVisibility == 'invisible')) { 
      parent.find(scope.mytarget).hide(); 
      element.html('+').addClass('invisible'); 
     } 
    }); 

    element.bind('click', function(event) { 
     event.preventDefault(); 
     scope.toggleVisibility(); 
    }); 

} 

}]); 

ответ

0

Только в случае, если кто полюбопытствовал я в конце концов выяснить это, и это в значительной степени так же, как указано выше, я просто перевел что-либо не связанное с DOM в службу:

tsApp.service('personalizationCookieService', ['$cookies', function($cookies) { 
if ($cookies.getObject('personalization')) { 
    var personalizationCookie = $cookies.getObject('personalization'); 
} else { 
    var personalizationCookie = []; 
} 

function setBlockToggleCookie(personalizationCookie) { 
    // Maximum value for cookie expiration, i.e. the closest thing to 
    // "never expire" is the year 2038. See: 
    // http://stackoverflow.com/questions/532635/javascript-cookie-with-no-expiration-date/532638#532638 and 
    // http://stackoverflow.com/questions/34586494/make-cookies-never-expire-with-angularjs 
    var expireDate = new Date(); 
    expireDate.setTime(2144232732000); 
    $cookies.putObject('personalization', personalizationCookie, { 
     'expires': expireDate 
    }); 
} 

return { 

    buildCookieObj: function(blockRef, blockVisibility) { 
     // If that item already exists remove so we can replace with new visibility setting 
     $.each(personalizationCookie, function(i) { 
      if (personalizationCookie[i].blockRef === blockRef) { 
       personalizationCookie.splice(i, 1); 
       return false; 
      } 
     }); 
     personalizationCookie.push({ 
      blockRef: blockRef, 
      blockVisibility: blockVisibility 
     }); 
     setBlockToggleCookie(personalizationCookie); 
    } 

}; 

}]);